Backed out changeset 24403e652d6d (bug 1141865)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 03 Jun 2015 12:42:03 +0200
changeset 277754 8b7268073cd82c258a45f5fb98aaec0bc055a20c
parent 277753 b003dbf1e2536d38220b85961422c95a3860faed
child 277755 a837cfd8ee1e05edfcd186e1fe3a14f1c25d0bd8
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1141865
milestone41.0a1
backs out24403e652d6dece7a575c167ffb33c9126d45b6f
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
Backed out changeset 24403e652d6d (bug 1141865)
js/src/builtin/Eval.cpp
js/src/builtin/Eval.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/SharedContext.h
js/src/jit-test/tests/debug/Frame-newTargetEval-01.js
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineFrame.cpp
js/src/jit/BaselineFrame.h
js/src/jit/BaselineFrameInfo.cpp
js/src/jit/BaselineFrameInfo.h
js/src/jit/BaselineJIT.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/Ion.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/JitFrameIterator.h
js/src/jit/LIR-Common.h
js/src/jit/Lowering.cpp
js/src/jit/MIR.h
js/src/jit/RematerializedFrame.cpp
js/src/jit/RematerializedFrame.h
js/src/jit/TypePolicy.cpp
js/src/jit/VMFunctions.h
js/src/tests/ecma_6/Class/newTargetContext.js
js/src/tests/ecma_6/Class/newTargetDirectInvoke.js
js/src/tests/ecma_6/Class/newTargetEval.js
js/src/vm/Debugger.cpp
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -356,27 +356,25 @@ EvalKernel(JSContext* cx, const CallArgs
             return false;
 
         if (compiled->strict())
             staticScope->setStrict();
 
         esg.setNewScript(compiled);
     }
 
-    // Look up the newTarget from the frame iterator.
-    Value newTargetVal = NullValue();
-    return ExecuteKernel(cx, esg.script(), *scopeobj, thisv, newTargetVal, ExecuteType(evalType),
+    return ExecuteKernel(cx, esg.script(), *scopeobj, thisv, ExecuteType(evalType),
                          NullFramePtr() /* evalInFrame */, args.rval().address());
 }
 
 bool
 js::DirectEvalStringFromIon(JSContext* cx,
                             HandleObject scopeobj, HandleScript callerScript,
-                            HandleValue thisValue, HandleValue newTargetValue,
-                            HandleString str, jsbytecode* pc, MutableHandleValue vp)
+                            HandleValue thisValue, HandleString str,
+                            jsbytecode* pc, MutableHandleValue vp)
 {
     AssertInnerizedScopeChain(cx, *scopeobj);
 
     Rooted<GlobalObject*> scopeObjGlobal(cx, &scopeobj->global());
     if (!GlobalObject::isRuntimeCodeGenEnabled(cx, scopeObjGlobal)) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL);
         return false;
     }
@@ -458,18 +456,18 @@ js::DirectEvalStringFromIon(JSContext* c
     RootedValue nthisValue(cx, thisValue);
     if (!callerScript->strict() && esg.script()->strict() && !thisValue.isObject()) {
         JSObject* obj = BoxNonStrictThis(cx, thisValue);
         if (!obj)
             return false;
         nthisValue = ObjectValue(*obj);
     }
 
-    return ExecuteKernel(cx, esg.script(), *scopeobj, nthisValue, newTargetValue,
-                         ExecuteType(DIRECT_EVAL), NullFramePtr() /* evalInFrame */, vp.address());
+    return ExecuteKernel(cx, esg.script(), *scopeobj, nthisValue, ExecuteType(DIRECT_EVAL),
+                         NullFramePtr() /* evalInFrame */, vp.address());
 }
 
 bool
 js::IndirectEval(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     Rooted<GlobalObject*> global(cx, &args.callee().global());
     return EvalKernel(cx, args, INDIRECT_EVAL, NullFramePtr(), global, nullptr);
@@ -531,17 +529,17 @@ js::ExecuteInGlobalAndReturnScope(JSCont
     JSObject* thisobj = GetThisObject(cx, global);
     if (!thisobj)
         return false;
 
     RootedValue thisv(cx, ObjectValue(*thisobj));
     RootedValue rval(cx);
     // XXXbz when this is fixed to pass in an actual ScopeObject, fix
     // up the assert in js::CloneFunctionObject accordingly.
-    if (!ExecuteKernel(cx, script, *scope, thisv, UndefinedValue(), EXECUTE_GLOBAL,
+    if (!ExecuteKernel(cx, script, *scope, thisv, EXECUTE_GLOBAL,
                        NullFramePtr() /* evalInFrame */, rval.address()))
     {
         return false;
     }
 
     scopeArg.set(scope);
     return true;
 }
--- a/js/src/builtin/Eval.h
+++ b/js/src/builtin/Eval.h
@@ -25,17 +25,17 @@ IndirectEval(JSContext* cx, unsigned arg
 // the result is returned in args.rval.
 extern bool
 DirectEval(JSContext* cx, const CallArgs& args);
 
 // Performs a direct eval called from Ion code.
 extern bool
 DirectEvalStringFromIon(JSContext* cx,
                         HandleObject scopeObj, HandleScript callerScript,
-                        HandleValue thisValue, HandleValue newTargetValue,
-                        HandleString str, jsbytecode * pc, MutableHandleValue vp);
+                        HandleValue thisValue, HandleString str,
+                        jsbytecode * pc, MutableHandleValue vp);
 
 // True iff fun is a built-in eval function.
 extern bool
 IsAnyBuiltinEval(JSFunction* fun);
 
 }  // namespace js
 #endif /* builtin_Eval_h */
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7831,50 +7831,28 @@ Parser<ParseHandler>::argumentList(Yield
         return false;
     }
     handler.setEndPosition(listNode, pos().end);
     return true;
 }
 
 template <typename ParseHandler>
 bool
-Parser<ParseHandler>::checkAllowedNestedSyntax(SharedContext::AllowedSyntax allowed,
-                                               SharedContext** allowingContext)
+Parser<ParseHandler>::checkAndMarkSuperScope()
 {
     for (GenericParseContext* gpc = pc; gpc; gpc = gpc->parent) {
         SharedContext* sc = gpc->sc;
-
-        // Arrow functions don't help decide whether we should allow nested
-        // syntax, as they don't store any of the necessary state for themselves.
-        if (sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow()) {
-            // For now (!), disallow new.target in arrow functions. This will
-            // change later in this bug!
-            if (allowed == SharedContext::AllowedSyntax::NewTarget)
-                return false;
-            continue;
-        }
-
-        if (!sc->allowSyntax(allowed))
-            return false;
-        if (allowingContext)
-            *allowingContext = sc;
-        return true;
-    }
-    return false;
-}
-
-template <typename ParseHandler>
-bool
-Parser<ParseHandler>::checkAndMarkSuperScope()
-{
-    SharedContext* foundContext = nullptr;
-    if (checkAllowedNestedSyntax(SharedContext::AllowedSyntax::SuperProperty, &foundContext)) {
-        if (foundContext->isFunctionBox())
-            foundContext->asFunctionBox()->setNeedsHomeObject();
-        return true;
+        if (sc->allowSuperProperty()) {
+            if (sc->isFunctionBox())
+                sc->asFunctionBox()->setNeedsHomeObject();
+            return true;
+        } else if (sc->isFunctionBox() && !sc->asFunctionBox()->function()->isArrow()) {
+            // super is not legal in normal functions.
+            break;
+        }
     }
     return false;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TokenKind tt, bool allowCallSyntax,
                                  InvokedPrediction invoked)
@@ -8661,17 +8639,19 @@ Parser<ParseHandler>::tryNewTarget(Node 
     if (!tokenStream.getToken(&next))
         return false;
     if (next != TOK_NAME || tokenStream.currentName() != context->names().target) {
         report(ParseError, false, null(), JSMSG_UNEXPECTED_TOKEN,
                "target", TokenKindToDesc(next));
         return false;
     }
 
-    if (!checkAllowedNestedSyntax(SharedContext::AllowedSyntax::NewTarget)) {
+    if (!pc->sc->isFunctionBox() || pc->sc->asFunctionBox()->isGenerator() ||
+        pc->sc->asFunctionBox()->function()->isArrow())
+    {
         reportWithOffset(ParseError, false, begin, JSMSG_BAD_NEWTARGET);
         return false;
     }
 
     newTarget = handler.newNewTarget(TokenPos(begin, pos().end));
     return !!newTarget;
 }
 
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -584,18 +584,16 @@ class Parser : private JS::AutoGCRooter,
     Node unaryExpr(YieldHandling yieldHandling, InvokedPrediction invoked = PredictUninvoked);
     Node memberExpr(YieldHandling yieldHandling, TokenKind tt, bool allowCallSyntax,
                     InvokedPrediction invoked = PredictUninvoked);
     Node primaryExpr(YieldHandling yieldHandling, TokenKind tt,
                      InvokedPrediction invoked = PredictUninvoked);
     Node parenExprOrGeneratorComprehension(YieldHandling yieldHandling);
     Node exprInParens(InHandling inHandling, YieldHandling yieldHandling);
 
-    bool checkAllowedNestedSyntax(SharedContext::AllowedSyntax allowed,
-                                  SharedContext** allowingContext = nullptr);
     bool tryNewTarget(Node& newTarget);
     bool checkAndMarkSuperScope();
 
     bool methodDefinition(YieldHandling yieldHandling, PropListType listType, Node propList,
                           Node propname, FunctionSyntaxKind kind, GeneratorKind generatorKind,
                           bool isStatic, JSOp Op);
 
     /*
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -225,37 +225,17 @@ class SharedContext
     bool needStrictChecks() {
         return strict() || extraWarnings;
     }
 
     bool isDotVariable(JSAtom* atom) const {
         return atom == context->names().dotGenerator || atom == context->names().dotGenRVal;
     }
 
-    enum class AllowedSyntax {
-        NewTarget,
-        SuperProperty
-    };
-    virtual bool allowSyntax(AllowedSyntax allowed) const = 0;
-
-  protected:
-    static bool FunctionAllowsSyntax(JSFunction* func, AllowedSyntax allowed)
-    {
-        MOZ_ASSERT(!func->isArrow());
-
-        switch (allowed) {
-          case AllowedSyntax::NewTarget:
-            // For now, disallow new.target inside generators
-            return !func->isGenerator();
-          case AllowedSyntax::SuperProperty:
-            return func->allowSuperProperty();
-          default:;
-        }
-        MOZ_CRASH("Unknown AllowedSyntax query");
-    }
+    virtual bool allowSuperProperty() const = 0;
 };
 
 class GlobalSharedContext : public SharedContext
 {
   private:
     Handle<StaticEvalObject*> staticEvalScope_;
 
   public:
@@ -264,27 +244,23 @@ class GlobalSharedContext : public Share
                         bool extraWarnings)
       : SharedContext(cx, directives, extraWarnings),
         staticEvalScope_(staticEvalScope)
     {}
 
     ObjectBox* toObjectBox() { return nullptr; }
     HandleObject evalStaticScope() const { return staticEvalScope_; }
 
-    bool allowSyntax(AllowedSyntax allowed) const {
+    bool allowSuperProperty() const {
         StaticScopeIter<CanGC> it(context, staticEvalScope_);
         for (; !it.done(); it++) {
-            if (it.type() == StaticScopeIter<CanGC>::Function) {
-                if (it.fun().isArrow()) {
-                    // For the moment, disallow new.target inside arrow functions
-                    if (allowed == AllowedSyntax::NewTarget)
-                        return false;
-                    continue;
-                }
-                return FunctionAllowsSyntax(&it.fun(), allowed);
+            if (it.type() == StaticScopeIter<CanGC>::Function &&
+                !it.fun().isArrow())
+            {
+                return it.fun().allowSuperProperty();
             }
         }
         return false;
     }
 };
 
 class FunctionBox : public ObjectBox, public SharedContext
 {
@@ -339,17 +315,17 @@ class FunctionBox : public ObjectBox, pu
     bool needsHomeObject()          const { return funCxFlags.needsHomeObject; }
 
     void setMightAliasLocals()             { funCxFlags.mightAliasLocals         = true; }
     void setHasExtensibleScope()           { funCxFlags.hasExtensibleScope       = true; }
     void setNeedsDeclEnvObject()           { funCxFlags.needsDeclEnvObject       = true; }
     void setArgumentsHasLocalBinding()     { funCxFlags.argumentsHasLocalBinding = true; }
     void setDefinitelyNeedsArgsObj()       { MOZ_ASSERT(funCxFlags.argumentsHasLocalBinding);
                                              funCxFlags.definitelyNeedsArgsObj   = true; }
-    void setNeedsHomeObject()              { MOZ_ASSERT(function()->allowSuperProperty());
+    void setNeedsHomeObject()              { MOZ_ASSERT(allowSuperProperty());
                                              funCxFlags.needsHomeObject          = true; }
 
     bool hasDefaults() const {
         return length != function()->nargs() - function()->hasRest();
     }
 
     // Return whether this or an enclosing function is being parsed and
     // validated as asm.js. Note: if asm.js validation fails, this will be false
@@ -371,23 +347,18 @@ class FunctionBox : public ObjectBox, pu
         // Note: this should be kept in sync with JSFunction::isHeavyweight().
         return bindings.hasAnyAliasedBindings() ||
                hasExtensibleScope() ||
                needsDeclEnvObject() ||
                needsHomeObject()    ||
                isGenerator();
     }
 
-    bool allowSyntax(AllowedSyntax allowed) const {
-        // For now (!) we don't allow new.target in generators, and can't
-        // check that for functions we haven't finished parsing, as they
-        // don't have initialized scripts. Check from our stashed bits instead.
-        if (allowed == AllowedSyntax::NewTarget)
-            return !isGenerator();
-        return FunctionAllowsSyntax(function(), allowed);
+    bool allowSuperProperty() const {
+        return function()->allowSuperProperty();
     }
 };
 
 inline FunctionBox*
 SharedContext::asFunctionBox()
 {
     MOZ_ASSERT(isFunctionBox());
     return static_cast<FunctionBox*>(this);
@@ -395,17 +366,16 @@ SharedContext::asFunctionBox()
 
 inline GlobalSharedContext*
 SharedContext::asGlobalSharedContext()
 {
     MOZ_ASSERT(!isFunctionBox());
     return static_cast<GlobalSharedContext*>(this);
 }
 
-
 // In generators, we treat all locals as aliased so that they get stored on the
 // heap.  This way there is less information to copy off the stack when
 // suspending, and back on when resuming.  It also avoids the need to create and
 // invalidate DebugScope proxies for unaliased locals in a generator frame, as
 // the generator frame will be copied out to the heap and released only by GC.
 inline bool
 SharedContext::allLocalsAliased()
 {
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/Frame-newTargetEval-01.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Test that new.target is acceptably usable in RematerializedFrames.
-
-load(libdir + "jitopts.js");
-
-if (!jitTogglesMatch(Opts_Ion2NoOffthreadCompilation))
-  quit();
-
-withJitOptions(Opts_Ion2NoOffthreadCompilation, function () {
-  var g = newGlobal();
-  var dbg = new Debugger;
-
-  g.toggle = function toggle(d, expected) {
-    if (d) {
-      dbg.addDebuggee(g);
-
-      var frame = dbg.getNewestFrame();
-      assertEq(frame.implementation, "ion");
-      assertEq(frame.constructing, true);
-
-      // CONGRATS IF THIS FAILS! You, proud saviour, have made new.target parse
-      // in debug frame evals (presumably by hooking up static scope walks).
-      // Uncomment the assert below for efaust's undying gratitude.
-      // Note that we use .name here because of CCW nonsense.
-      assertEq(frame.eval('new.target').throw.unsafeDereference().name, "SyntaxError");
-      // assertEq(frame.eval('new.target').value.unsafeDereference(), expected);
-    }
-  };
-
-  g.eval("" + function f(d) { new g(d, g, 15); });
-
-  g.eval("" + function g(d, expected) { toggle(d, expected); });
-
-  g.eval("(" + function test() {
-    for (var i = 0; i < 5; i++)
-      f(false);
-    f(true);
-  } + ")();");
-});
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1508,21 +1508,16 @@ BaselineCompiler::storeValue(const Stack
       case StackValue::ArgSlot:
         masm.loadValue(frame.addressOfArg(source->argSlot()), scratch);
         masm.storeValue(scratch, dest);
         break;
       case StackValue::ThisSlot:
         masm.loadValue(frame.addressOfThis(), scratch);
         masm.storeValue(scratch, dest);
         break;
-      case StackValue::EvalNewTargetSlot:
-        MOZ_ASSERT(script->isForEval());
-        masm.loadValue(frame.addressOfEvalNewTarget(), scratch);
-        masm.storeValue(scratch, dest);
-        break;
       case StackValue::Stack:
         masm.loadValue(frame.addressOfStackValue(source), scratch);
         masm.storeValue(scratch, dest);
         break;
       default:
         MOZ_CRASH("Invalid kind");
     }
 }
@@ -2681,21 +2676,16 @@ BaselineCompiler::emit_JSOP_SETARG()
 
     uint32_t arg = GET_ARGNO(pc);
     return emitFormalArgAccess(arg, /* get = */ false);
 }
 
 bool
 BaselineCompiler::emit_JSOP_NEWTARGET()
 {
-    if (script->isForEval()) {
-        frame.pushEvalNewTarget();
-        return true;
-    }
-
     MOZ_ASSERT(function());
     frame.syncStack(0);
 
     // if (!isConstructing()) push(undefined)
     Label constructing, done;
     masm.branchTestPtr(Assembler::NonZero, frame.addressOfCalleeToken(),
                        Imm32(CalleeToken_FunctionConstructing), &constructing);
     masm.moveValue(UndefinedValue(), R0);
--- a/js/src/jit/BaselineFrame.cpp
+++ b/js/src/jit/BaselineFrame.cpp
@@ -43,20 +43,18 @@ BaselineFrame::trace(JSTracer* trc, JitF
     // Mark scope chain, if it exists.
     if (scopeChain_)
         TraceRoot(trc, &scopeChain_, "baseline-scopechain");
 
     // Mark return value.
     if (hasReturnValue())
         TraceRoot(trc, returnValue().address(), "baseline-rval");
 
-    if (isEvalFrame()) {
+    if (isEvalFrame())
         TraceRoot(trc, &evalScript_, "baseline-evalscript");
-        TraceRoot(trc, evalNewTargetAddress(), "baseline-evalNewTarget");
-    }
 
     if (hasArgsObj())
         TraceRoot(trc, &argsObj_, "baseline-args-obj");
 
     // Mark locals and stack values.
     JSScript* script = this->script();
     size_t nfixed = script->nfixed();
     size_t nlivefixed = script->nbodyfixed();
--- a/js/src/jit/BaselineFrame.h
+++ b/js/src/jit/BaselineFrame.h
@@ -212,35 +212,16 @@ class BaselineFrame
                          offsetOfThis());
     }
     Value* argv() const {
         return (Value*)(reinterpret_cast<const uint8_t*>(this) +
                          BaselineFrame::Size() +
                          offsetOfArg(0));
     }
 
-  private:
-    Value* evalNewTargetAddress() const {
-        MOZ_ASSERT(isEvalFrame());
-        return (Value*)(reinterpret_cast<const uint8_t*>(this) +
-                        BaselineFrame::Size() +
-                        offsetOfEvalNewTarget());
-    }
-
-  public:
-    Value newTarget() const {
-        if (isEvalFrame())
-            return *evalNewTargetAddress();
-        if (isConstructing())
-            return *(Value*)(reinterpret_cast<const uint8_t*>(this) +
-                             BaselineFrame::Size() +
-                             offsetOfArg(Max(numFormalArgs(), numActualArgs())));
-        return UndefinedValue();
-    }
-
     bool copyRawFrameSlots(AutoValueVector* vec) const;
 
     bool hasReturnValue() const {
         return flags_ & HAS_RVAL;
     }
     MutableHandleValue returnValue() {
         if (!hasReturnValue())
             addressOfReturnValue()->setUndefined();
@@ -413,19 +394,16 @@ class BaselineFrame
 
     // Methods below are used by the compiler.
     static size_t offsetOfCalleeToken() {
         return FramePointerOffset + js::jit::JitFrameLayout::offsetOfCalleeToken();
     }
     static size_t offsetOfThis() {
         return FramePointerOffset + js::jit::JitFrameLayout::offsetOfThis();
     }
-    static size_t offsetOfEvalNewTarget() {
-        return offsetOfArg(0);
-    }
     static size_t offsetOfArg(size_t index) {
         return FramePointerOffset + js::jit::JitFrameLayout::offsetOfActualArg(index);
     }
     static size_t offsetOfNumActualArgs() {
         return FramePointerOffset + js::jit::JitFrameLayout::offsetOfNumActualArgs();
     }
     static size_t Size() {
         return sizeof(BaselineFrame);
--- a/js/src/jit/BaselineFrameInfo.cpp
+++ b/js/src/jit/BaselineFrameInfo.cpp
@@ -34,20 +34,16 @@ FrameInfo::sync(StackValue* val)
         masm.pushValue(addressOfLocal(val->localSlot()));
         break;
       case StackValue::ArgSlot:
         masm.pushValue(addressOfArg(val->argSlot()));
         break;
       case StackValue::ThisSlot:
         masm.pushValue(addressOfThis());
         break;
-      case StackValue::EvalNewTargetSlot:
-        MOZ_ASSERT(script->isForEval());
-        masm.pushValue(addressOfEvalNewTarget());
-        break;
       case StackValue::Register:
         masm.pushValue(val->reg());
         break;
       case StackValue::Constant:
         masm.pushValue(val->constant());
         break;
       default:
         MOZ_CRASH("Invalid kind");
@@ -94,19 +90,16 @@ FrameInfo::popValue(ValueOperand dest)
         masm.loadValue(addressOfLocal(val->localSlot()), dest);
         break;
       case StackValue::ArgSlot:
         masm.loadValue(addressOfArg(val->argSlot()), dest);
         break;
       case StackValue::ThisSlot:
         masm.loadValue(addressOfThis(), dest);
         break;
-      case StackValue::EvalNewTargetSlot:
-        masm.loadValue(addressOfEvalNewTarget(), dest);
-        break;
       case StackValue::Stack:
         masm.popValue(dest);
         break;
       case StackValue::Register:
         masm.moveValue(val->reg(), dest);
         break;
       default:
         MOZ_CRASH("Invalid kind");
--- a/js/src/jit/BaselineFrameInfo.h
+++ b/js/src/jit/BaselineFrameInfo.h
@@ -49,18 +49,17 @@ class StackValue
 {
   public:
     enum Kind {
         Constant,
         Register,
         Stack,
         LocalSlot,
         ArgSlot,
-        ThisSlot,
-        EvalNewTargetSlot
+        ThisSlot
 #ifdef DEBUG
         // In debug builds, assert Kind is initialized.
         , Uninitialized
 #endif
     };
 
   private:
     Kind kind_;
@@ -146,20 +145,16 @@ class StackValue
         kind_ = ArgSlot;
         data.arg.slot = slot;
         knownType_ = JSVAL_TYPE_UNKNOWN;
     }
     void setThis() {
         kind_ = ThisSlot;
         knownType_ = JSVAL_TYPE_UNKNOWN;
     }
-    void setEvalNewTarget() {
-        kind_ = EvalNewTargetSlot;
-        knownType_ = JSVAL_TYPE_UNKNOWN;
-    }
     void setStack() {
         kind_ = Stack;
         knownType_ = JSVAL_TYPE_UNKNOWN;
     }
 };
 
 enum StackAdjustment { AdjustStack, DontAdjustStack };
 
@@ -259,41 +254,32 @@ class FrameInfo
     inline void pushArg(uint32_t arg) {
         StackValue* sv = rawPush();
         sv->setArgSlot(arg);
     }
     inline void pushThis() {
         StackValue* sv = rawPush();
         sv->setThis();
     }
-    inline void pushEvalNewTarget() {
-        MOZ_ASSERT(script->isForEval());
-        StackValue* sv = rawPush();
-        sv->setEvalNewTarget();
-    }
-
     inline void pushScratchValue() {
         masm.pushValue(addressOfScratchValue());
         StackValue* sv = rawPush();
         sv->setStack();
     }
     inline Address addressOfLocal(size_t local) const {
         MOZ_ASSERT(local < nlocals());
         return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfLocal(local));
     }
     Address addressOfArg(size_t arg) const {
         MOZ_ASSERT(arg < nargs());
         return Address(BaselineFrameReg, BaselineFrame::offsetOfArg(arg));
     }
     Address addressOfThis() const {
         return Address(BaselineFrameReg, BaselineFrame::offsetOfThis());
     }
-    Address addressOfEvalNewTarget() const {
-        return Address(BaselineFrameReg, BaselineFrame::offsetOfEvalNewTarget());
-    }
     Address addressOfCalleeToken() const {
         return Address(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
     }
     Address addressOfScopeChain() const {
         return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfScopeChain());
     }
     Address addressOfFlags() const {
         return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags());
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -176,17 +176,16 @@ jit::EnterBaselineAtBranch(JSContext* cx
     if (fp->isDebuggee()) {
         MOZ_RELEASE_ASSERT(baseline->hasDebugInstrumentation());
         data.jitcode += MacroAssembler::ToggledCallSize(data.jitcode);
     }
 
     data.osrFrame = fp;
     data.osrNumStackValues = fp->script()->nfixed() + cx->interpreterRegs().stackDepth();
 
-    AutoValueVector vals(cx);
     RootedValue thisv(cx);
 
     if (fp->isNonEvalFunctionFrame()) {
         data.constructing = fp->isConstructing();
         data.numActualArgs = fp->numActualArgs();
         data.maxArgc = Max(fp->numActualArgs(), fp->numFormalArgs()) + 1; // +1 = include |this|
         data.maxArgv = fp->argv() - 1; // -1 = include |this|
         data.scopeChain = nullptr;
@@ -199,31 +198,16 @@ jit::EnterBaselineAtBranch(JSContext* cx
         data.maxArgv = thisv.address();
         data.scopeChain = fp->scopeChain();
 
         // For eval function frames, set the callee token to the enclosing function.
         if (fp->isFunctionFrame())
             data.calleeToken = CalleeToToken(&fp->callee(), /* constructing = */ false);
         else
             data.calleeToken = CalleeToToken(fp->script());
-
-        if (fp->isEvalFrame()) {
-            if (!vals.reserve(2))
-                return JitExec_Aborted;
-
-            vals.infallibleAppend(thisv);
-            
-            if (fp->isFunctionFrame())
-                vals.infallibleAppend(fp->newTarget());
-            else
-                vals.infallibleAppend(NullValue());
-
-            data.maxArgc = 2;
-            data.maxArgv = vals.begin();
-        }
     }
 
     TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
     TraceLogStopEvent(logger, TraceLogger_Interpreter);
     TraceLogStartEvent(logger, TraceLogger_Baseline);
 
     JitExecStatus status = EnterBaseline(cx, data);
     if (status != JitExec_Ok)
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -3480,29 +3480,28 @@ CodeGenerator::visitFilterArgumentsOrEva
     masm.branchTestString(Assembler::NotEqual, input, &done);
 
     emitFilterArgumentsOrEval(lir, masm.extractString(input, ToRegister(lir->temp3())),
                               ToRegister(lir->temp1()), ToRegister(lir->temp2()));
 
     masm.bind(&done);
 }
 
-typedef bool (*DirectEvalSFn)(JSContext*, HandleObject, HandleScript, HandleValue, HandleValue,
-                              HandleString, jsbytecode*, MutableHandleValue);
+typedef bool (*DirectEvalSFn)(JSContext*, HandleObject, HandleScript, HandleValue, HandleString,
+                              jsbytecode*, MutableHandleValue);
 static const VMFunction DirectEvalStringInfo = FunctionInfo<DirectEvalSFn>(DirectEvalStringFromIon);
 
 void
 CodeGenerator::visitCallDirectEval(LCallDirectEval* lir)
 {
     Register scopeChain = ToRegister(lir->getScopeChain());
     Register string = ToRegister(lir->getString());
 
     pushArg(ImmPtr(lir->mir()->pc()));
     pushArg(string);
-    pushArg(ToValue(lir, LCallDirectEval::NewTarget));
     pushArg(ToValue(lir, LCallDirectEval::ThisValue));
     pushArg(ImmGCPtr(gen->info().script()));
     pushArg(scopeChain);
 
     callVM(DirectEvalStringInfo, lir);
 }
 
 void
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2590,32 +2590,16 @@ jit::SetEnterJitData(JSContext* cx, Ente
         data.calleeToken = CalleeToToken(state.script());
 
         if (state.script()->isForEval() &&
             !(state.asExecute()->type() & InterpreterFrame::GLOBAL))
         {
             ScriptFrameIter iter(cx);
             if (iter.isFunctionFrame())
                 data.calleeToken = CalleeToToken(iter.callee(cx), /* constructing = */ false);
-                
-            // Push newTarget onto the stack, as well as Argv.
-            if (!vals.reserve(2))
-                return false;
-            
-            data.maxArgc = 2;
-            data.maxArgv = vals.begin();
-            vals.infallibleAppend(state.asExecute()->thisv());
-            if (iter.isFunctionFrame()) { 
-                if (state.asExecute()->newTarget().isNull())
-                    vals.infallibleAppend(iter.newTarget());
-                else
-                    vals.infallibleAppend(state.asExecute()->newTarget());
-            } else {
-                vals.infallibleAppend(NullValue());
-            }
         }
     }
 
     return true;
 }
 
 JitExecStatus
 jit::IonCannon(JSContext* cx, RunState& state)
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -6422,20 +6422,16 @@ IonBuilder::jsop_eval(uint32_t argc)
             current->push(string);
             TemporaryTypeSet* types = bytecodeTypes(pc);
             return pushTypeBarrier(string, types, BarrierKind::TypeSet);
         }
 
         current->pushSlot(info().thisSlot());
         MDefinition* thisValue = current->pop();
 
-        if (!jsop_newtarget())
-            return false;
-        MDefinition* newTargetValue = current->pop();
-
         // Try to pattern match 'eval(v + "()")'. In this case v is likely a
         // name on the scope chain and the eval is performing a call on that
         // value. Use a dynamic scope chain lookup rather than a full eval.
         if (string->isConcat() &&
             string->getOperand(1)->isConstantValue() &&
             string->getOperand(1)->constantValue().isString())
         {
             JSAtom* atom = &string->getOperand(1)->constantValue().toString()->asAtom();
@@ -6454,18 +6450,17 @@ IonBuilder::jsop_eval(uint32_t argc)
 
                 return makeCall(nullptr, evalCallInfo);
             }
         }
 
         MInstruction* filterArguments = MFilterArgumentsOrEval::New(alloc(), string);
         current->add(filterArguments);
 
-        MInstruction* ins = MCallDirectEval::New(alloc(), scopeChain, string,
-                                                 thisValue, newTargetValue, pc);
+        MInstruction* ins = MCallDirectEval::New(alloc(), scopeChain, string, thisValue, pc);
         current->add(ins);
         current->push(ins);
 
         TemporaryTypeSet* types = bytecodeTypes(pc);
         return resumeAfter(ins) && pushTypeBarrier(ins, types, BarrierKind::TypeSet);
     }
 
     return jsop_call(argc, /* constructing = */ false);
@@ -9431,22 +9426,16 @@ IonBuilder::jsop_arguments()
     MOZ_ASSERT(lazyArguments_);
     current->push(lazyArguments_);
     return true;
 }
 
 bool
 IonBuilder::jsop_newtarget()
 {
-    if (!info().funMaybeLazy()) {
-        MOZ_ASSERT(!info().script()->isForEval());
-        pushConstant(NullValue());
-        return true;
-    }
-
     MOZ_ASSERT(info().funMaybeLazy());
     if (inliningDepth_ == 0) {
         MNewTarget* newTarget = MNewTarget::New(alloc());
         current->add(newTarget);
         current->push(newTarget);
         return true;
     }
 
--- a/js/src/jit/JitFrameIterator.h
+++ b/js/src/jit/JitFrameIterator.h
@@ -696,18 +696,18 @@ class InlineFrameIterator
         if (more())
             return numActualArgs_;
 
         return frame_->numActualArgs();
     }
 
     template <class ArgOp, class LocalOp>
     void readFrameArgsAndLocals(JSContext* cx, ArgOp& argOp, LocalOp& localOp,
-                                JSObject** scopeChain, bool* hasCallObj,
-                                Value* rval, ArgumentsObject** argsObj, Value* thisv,
+                                JSObject** scopeChain, bool* hasCallObj, Value* rval,
+                                ArgumentsObject** argsObj, Value* thisv,
                                 ReadFrameArgsBehavior behavior,
                                 MaybeReadFallback& fallback) const
     {
         SnapshotIterator s(si_);
 
         // Read the scope chain.
         if (scopeChain) {
             Value scopeChainValue = s.maybeRead(fallback);
@@ -757,23 +757,23 @@ class InlineFrameIterator
                     for (unsigned j = 0; j < skip; j++)
                         parent_s.skip();
 
                     // Get the overflown arguments
                     MaybeReadFallback unusedFallback;
                     parent_s.skip(); // scope chain
                     parent_s.skip(); // return value
                     parent_s.readFunctionFrameArgs(argOp, nullptr, nullptr,
-                                                   nformal, nactual + isConstructing(), it.script(),
+                                                   nformal, nactual, it.script(),
                                                    fallback);
                 } else {
                     // There is no parent frame to this inlined frame, we can read
                     // from the frame's Value vector directly.
                     Value* argv = frame_->actualArgs();
-                    for (unsigned i = nformal; i < nactual + isConstructing(); i++)
+                    for (unsigned i = nformal; i < nactual; i++)
                         argOp(argv[i]);
                 }
             }
         }
 
         // At this point we've read all the formals in s, and can read the
         // locals.
         for (unsigned i = 0; i < script()->nfixed(); i++)
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -1922,29 +1922,28 @@ class LFilterArgumentsOrEvalV : public L
     const LDefinition* temp2() {
         return getTemp(1);
     }
     const LDefinition* temp3() {
         return getTemp(2);
     }
 };
 
-class LCallDirectEval : public LCallInstructionHelper<BOX_PIECES, 2 + (2 * BOX_PIECES), 0>
+class LCallDirectEval : public LCallInstructionHelper<BOX_PIECES, 2 + BOX_PIECES, 0>
 {
   public:
     LIR_HEADER(CallDirectEval)
 
     LCallDirectEval(const LAllocation& scopeChain, const LAllocation& string)
     {
         setOperand(0, scopeChain);
         setOperand(1, string);
     }
 
     static const size_t ThisValue = 2;
-    static const size_t NewTarget = 2 + BOX_PIECES;
 
     MCallDirectEval* mir() const {
         return mir_->toCallDirectEval();
     }
 
     const LAllocation* getScopeChain() {
         return getOperand(0);
     }
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -604,22 +604,20 @@ LIRGenerator::visitCallDirectEval(MCallD
 {
     MDefinition* scopeChain = ins->getScopeChain();
     MOZ_ASSERT(scopeChain->type() == MIRType_Object);
 
     MDefinition* string = ins->getString();
     MOZ_ASSERT(string->type() == MIRType_String);
 
     MDefinition* thisValue = ins->getThisValue();
-    MDefinition* newTargetValue = ins->getNewTargetValue();
 
     LInstruction* lir = new(alloc()) LCallDirectEval(useRegisterAtStart(scopeChain),
                                                      useRegisterAtStart(string));
     useBoxAtStart(lir, LCallDirectEval::ThisValue, thisValue);
-    useBoxAtStart(lir, LCallDirectEval::NewTarget, newTargetValue);
 
     defineReturn(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 static JSOp
 ReorderComparison(JSOp op, MDefinition** lhsp, MDefinition** rhsp)
 {
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -4064,56 +4064,51 @@ class MFilterArgumentsOrEval
         return getOperand(0);
     }
     bool possiblyCalls() const override {
         return true;
     }
 };
 
 class MCallDirectEval
-  : public MAryInstruction<4>,
-    public Mix4Policy<ObjectPolicy<0>,
+  : public MAryInstruction<3>,
+    public Mix3Policy<ObjectPolicy<0>,
                       StringPolicy<1>,
-                      BoxPolicy<2>,
-                      BoxPolicy<3> >::Data
+                      BoxPolicy<2> >::Data
 {
   protected:
     MCallDirectEval(MDefinition* scopeChain, MDefinition* string, MDefinition* thisValue,
-                    MDefinition* newTargetValue, jsbytecode* pc)
+                    jsbytecode* pc)
         : pc_(pc)
     {
         initOperand(0, scopeChain);
         initOperand(1, string);
         initOperand(2, thisValue);
-        initOperand(3, newTargetValue);
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(CallDirectEval)
 
     static MCallDirectEval*
     New(TempAllocator& alloc, MDefinition* scopeChain, MDefinition* string, MDefinition* thisValue,
-        MDefinition* newTargetValue, jsbytecode* pc)
-    {
-        return new(alloc) MCallDirectEval(scopeChain, string, thisValue, newTargetValue, pc);
+        jsbytecode* pc)
+    {
+        return new(alloc) MCallDirectEval(scopeChain, string, thisValue, pc);
     }
 
     MDefinition* getScopeChain() const {
         return getOperand(0);
     }
     MDefinition* getString() const {
         return getOperand(1);
     }
     MDefinition* getThisValue() const {
         return getOperand(2);
     }
-    MDefinition* getNewTargetValue() const {
-        return getOperand(3);
-    }
 
     jsbytecode* pc() const {
         return pc_;
     }
 
     bool possiblyCalls() const override {
         return true;
     }
--- a/js/src/jit/RematerializedFrame.cpp
+++ b/js/src/jit/RematerializedFrame.cpp
@@ -30,17 +30,16 @@ struct CopyValueToRematerializedFrame
         *slots++ = v;
     }
 };
 
 RematerializedFrame::RematerializedFrame(JSContext* cx, uint8_t* top, unsigned numActualArgs,
                                          InlineFrameIterator& iter, MaybeReadFallback& fallback)
   : prevUpToDate_(false),
     isDebuggee_(iter.script()->isDebuggee()),
-    isConstructing_(iter.isConstructing()),
     top_(top),
     pc_(iter.pc()),
     frameNo_(iter.frameNo()),
     numActualArgs_(numActualArgs),
     script_(iter.script())
 {
     if (iter.isFunctionFrame())
         callee_ = iter.callee(fallback);
@@ -53,17 +52,17 @@ RematerializedFrame::RematerializedFrame
                                 fallback);
 }
 
 /* static */ RematerializedFrame*
 RematerializedFrame::New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
                          MaybeReadFallback& fallback)
 {
     unsigned numFormals = iter.isFunctionFrame() ? iter.calleeTemplate()->nargs() : 0;
-    unsigned argSlots = Max(numFormals, iter.numActualArgs()) + iter.isConstructing();
+    unsigned argSlots = Max(numFormals, iter.numActualArgs());
     size_t numBytes = sizeof(RematerializedFrame) +
         (argSlots + iter.script()->nfixed()) * sizeof(Value) -
         sizeof(Value); // 1 Value included in sizeof(RematerializedFrame)
 
     void* buf = cx->pod_calloc<uint8_t>(numBytes);
     if (!buf)
         return nullptr;
 
@@ -154,18 +153,17 @@ void
 RematerializedFrame::mark(JSTracer* trc)
 {
     TraceRoot(trc, &script_, "remat ion frame script");
     TraceRoot(trc, &scopeChain_, "remat ion frame scope chain");
     if (callee_)
         TraceRoot(trc, &callee_, "remat ion frame callee");
     TraceRoot(trc, &returnValue_, "remat ion frame return value");
     TraceRoot(trc, &thisValue_, "remat ion frame this");
-    TraceRootRange(trc, numActualArgs_ + isConstructing_ + script_->nfixed(),
-                   slots_, "remat ion frame stack");
+    TraceRootRange(trc, numActualArgs_ + script_->nfixed(), slots_, "remat ion frame stack");
 }
 
 void
 RematerializedFrame::dump()
 {
     fprintf(stderr, " Rematerialized Ion Frame%s\n", inlined() ? " (inlined)" : "");
     if (isFunctionFrame()) {
         fprintf(stderr, "  callee fun: ");
--- a/js/src/jit/RematerializedFrame.h
+++ b/js/src/jit/RematerializedFrame.h
@@ -27,19 +27,16 @@ class RematerializedFrame
     bool prevUpToDate_;
 
     // Propagated to the Baseline frame once this is popped.
     bool isDebuggee_;
 
     // Has a call object been pushed?
     bool hasCallObj_;
 
-    // Is this frame constructing?
-    bool isConstructing_;
-
     // The fp of the top frame associated with this possibly inlined frame.
     uint8_t* top_;
 
     // The bytecode at the time of rematerialization.
     jsbytecode* pc_;
 
     size_t frameNo_;
     unsigned numActualArgs_;
@@ -160,32 +157,28 @@ class RematerializedFrame
     }
     Value calleev() const {
         return ObjectValue(*callee());
     }
     Value& thisValue() {
         return thisValue_;
     }
 
-    bool isConstructing() const {
-        return isConstructing_;
-    }
-
     unsigned numFormalArgs() const {
         return maybeFun() ? fun()->nargs() : 0;
     }
     unsigned numActualArgs() const {
         return numActualArgs_;
     }
 
     Value* argv() {
         return slots_;
     }
     Value* locals() {
-        return slots_ + numActualArgs_ + isConstructing_;
+        return slots_ + numActualArgs_;
     }
 
     Value& unaliasedLocal(unsigned i) {
         MOZ_ASSERT(i < script()->nfixed());
         return locals()[i];
     }
     Value& unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
         MOZ_ASSERT(i < numFormalArgs());
@@ -195,23 +188,16 @@ class RematerializedFrame
     }
     Value& unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
         MOZ_ASSERT(i < numActualArgs());
         MOZ_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals());
         MOZ_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i));
         return argv()[i];
     }
 
-    Value newTarget() {
-        MOZ_ASSERT(isFunctionFrame());
-        if (isConstructing())
-            return argv()[numActualArgs()];
-        return UndefinedValue();
-    }
-
     Value returnValue() const {
         return returnValue_;
     }
 
     void mark(JSTracer* trc);
     void dump();
 };
 
--- a/js/src/jit/TypePolicy.cpp
+++ b/js/src/jit/TypePolicy.cpp
@@ -1147,17 +1147,16 @@ FilterTypeSetPolicy::adjustInputs(TempAl
     _(Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, BoxPolicy<2> >)         \
     _(Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, ObjectPolicy<2> >)      \
     _(Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, BoxPolicy<2> >)         \
     _(Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, IntPolicy<2> >)         \
     _(Mix3Policy<ObjectPolicy<0>, ObjectPolicy<1>, IntPolicy<2> >)      \
     _(Mix3Policy<StringPolicy<0>, IntPolicy<1>, IntPolicy<2>>)          \
     _(Mix3Policy<StringPolicy<0>, ObjectPolicy<1>, StringPolicy<2> >)   \
     _(Mix3Policy<StringPolicy<0>, StringPolicy<1>, StringPolicy<2> >)   \
-    _(Mix4Policy<ObjectPolicy<0>, StringPolicy<1>, BoxPolicy<2>, BoxPolicy<3>>) \
     _(Mix4Policy<ObjectPolicy<0>, IntPolicy<1>, IntPolicy<2>, IntPolicy<3>>) \
     _(Mix4Policy<SimdScalarPolicy<0>, SimdScalarPolicy<1>, SimdScalarPolicy<2>, SimdScalarPolicy<3> >) \
     _(MixPolicy<BoxPolicy<0>, ObjectPolicy<1> >)                        \
     _(MixPolicy<ConvertToStringPolicy<0>, ConvertToStringPolicy<1> >)   \
     _(MixPolicy<ConvertToStringPolicy<0>, ObjectPolicy<1> >)            \
     _(MixPolicy<DoublePolicy<0>, DoublePolicy<1> >)                     \
     _(MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >)                        \
     _(MixPolicy<ObjectPolicy<0>, ConvertToStringPolicy<1> >)            \
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -441,17 +441,16 @@ template <> struct MatchContext<Exclusiv
 };
 
 #define FOR_EACH_ARGS_1(Macro, Sep, Last) Macro(1) Last(1)
 #define FOR_EACH_ARGS_2(Macro, Sep, Last) FOR_EACH_ARGS_1(Macro, Sep, Sep) Macro(2) Last(2)
 #define FOR_EACH_ARGS_3(Macro, Sep, Last) FOR_EACH_ARGS_2(Macro, Sep, Sep) Macro(3) Last(3)
 #define FOR_EACH_ARGS_4(Macro, Sep, Last) FOR_EACH_ARGS_3(Macro, Sep, Sep) Macro(4) Last(4)
 #define FOR_EACH_ARGS_5(Macro, Sep, Last) FOR_EACH_ARGS_4(Macro, Sep, Sep) Macro(5) Last(5)
 #define FOR_EACH_ARGS_6(Macro, Sep, Last) FOR_EACH_ARGS_5(Macro, Sep, Sep) Macro(6) Last(6)
-#define FOR_EACH_ARGS_7(Macro, Sep, Last) FOR_EACH_ARGS_6(Macro, Sep, Sep) Macro(7) Last(7)
 
 #define COMPUTE_INDEX(NbArg) NbArg
 #define COMPUTE_OUTPARAM_RESULT(NbArg) OutParamToDataType<A ## NbArg>::result
 #define COMPUTE_OUTPARAM_ROOT(NbArg) OutParamToRootType<A ## NbArg>::result
 #define COMPUTE_ARG_PROP(NbArg) (TypeToArgProperties<A ## NbArg>::result << (2 * (NbArg - 1)))
 #define COMPUTE_ARG_ROOT(NbArg) (uint64_t(TypeToRootType<A ## NbArg>::result) << (3 * (NbArg - 1)))
 #define COMPUTE_ARG_FLOAT(NbArg) (TypeToPassInFloatReg<A ## NbArg>::result) << (NbArg - 1)
 #define SEP_OR(_) |
@@ -581,25 +580,18 @@ template <class R, class Context, class 
 };
 
 template <class R, class Context, class A1, class A2, class A3, class A4, class A5, class A6>
     struct FunctionInfo<R (*)(Context, A1, A2, A3, A4, A5, A6)> : public VMFunction {
     typedef R (*pf)(Context, A1, A2, A3, A4, A5, A6);
     FUNCTION_INFO_STRUCT_BODY(FOR_EACH_ARGS_6)
 };
 
-template <class R, class Context, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-    struct FunctionInfo<R (*)(Context, A1, A2, A3, A4, A5, A6, A7)> : public VMFunction {
-    typedef R (*pf)(Context, A1, A2, A3, A4, A5, A6, A7);
-    FUNCTION_INFO_STRUCT_BODY(FOR_EACH_ARGS_7)
-};
-
 #undef FUNCTION_INFO_STRUCT_BODY
 
-#undef FOR_EACH_ARGS_7
 #undef FOR_EACH_ARGS_6
 #undef FOR_EACH_ARGS_5
 #undef FOR_EACH_ARGS_4
 #undef FOR_EACH_ARGS_3
 #undef FOR_EACH_ARGS_2
 #undef FOR_EACH_ARGS_1
 
 #undef COMPUTE_INDEX
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Class/newTargetContext.js
@@ -0,0 +1,11 @@
+// new.target is valid inside Function() invocations
+var func = new Function("new.target");
+
+// new.target is invalid inside eval, even (for now!) eval inside a function.
+assertThrowsInstanceOf(() => eval('new.target'), SyntaxError);
+
+function evalInFunction() { eval('new.target'); }
+assertThrowsInstanceOf(() => evalInFunction(), SyntaxError);
+
+if (typeof reportCompare === "function")
+    reportCompare(0,0,"OK");
--- a/js/src/tests/ecma_6/Class/newTargetDirectInvoke.js
+++ b/js/src/tests/ecma_6/Class/newTargetDirectInvoke.js
@@ -1,11 +1,8 @@
-// new.target is valid inside Function() invocations
-var func = new Function("new.target");
-
 // Note that this will also test new.target in ion inlines. When the toplevel
 // script is compiled, assertNewTarget will be inlined.
 function assertNewTarget(expected, unused) { assertEq(new.target, expected); }
 
 // Test non-constructing invocations, with arg underflow, overflow, and correct
 // numbers
 for (let i = 0; i < 100; i++)
     assertNewTarget(undefined, null);
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetEval.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Eval of new.target is invalid outside functions.
-try {
-    eval('new.target');
-    assertEq(false, true);
-} catch (e if e instanceof SyntaxError) { }
-
-// new.target is (for now!) invalid inside arrow functions, or eval inside arrow
-// functions.
-assertThrowsInstanceOf(() => eval('new.target'), SyntaxError);
-
-// new.target is invalid inside indirect eval.
-let ieval = eval;
-try {
-    (function () ieval('new.target'))();
-    assertEq(false, true);
-} catch (e if e instanceof SyntaxError) { }
-
-function assertNewTarget(expected) {
-    assertEq(eval('new.target'), expected);
-
-    // Also test nestings "by induction"
-    assertEq(eval('eval("new.target")'), expected);
-    assertEq(eval("eval('eval(`new.target`)')"), expected);
-}
-
-const ITERATIONS = 550;
-for (let i = 0; i < ITERATIONS; i++)
-    assertNewTarget(undefined);
-
-for (let i = 0; i < ITERATIONS; i++)
-    new assertNewTarget(assertNewTarget);
-
-if (typeof reportCompare === "function")
-    reportCompare(0,0,"OK");
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -6282,17 +6282,17 @@ EvaluateInEnv(JSContext* cx, Handle<Env*
     if (!script)
         return false;
 
     if (script->strict())
         staticScope->setStrict();
 
     script->setActiveEval();
     ExecuteType type = !frame ? EXECUTE_DEBUG_GLOBAL : EXECUTE_DEBUG;
-    return ExecuteKernel(cx, script, *env, thisv, NullValue(), type, frame, rval.address());
+    return ExecuteKernel(cx, script, *env, thisv, type, frame, rval.address());
 }
 
 enum EvalBindings { EvalHasExtraBindings = true, EvalWithDefaultBindings = false };
 
 static bool
 DebuggerGenericEval(JSContext* cx, const char* fullMethodName, const Value& code,
                     EvalBindings evalWithBindings, HandleValue bindings, HandleValue options,
                     MutableHandleValue vp, Debugger* dbg, HandleObject scope,
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -361,18 +361,18 @@ InterpreterFrame*
 InvokeState::pushInterpreterFrame(JSContext* cx)
 {
     return cx->runtime()->interpreterStack().pushInvokeFrame(cx, args_, initial_);
 }
 
 InterpreterFrame*
 ExecuteState::pushInterpreterFrame(JSContext* cx)
 {
-    return cx->runtime()->interpreterStack().pushExecuteFrame(cx, script_, thisv_, newTargetValue_,
-                                                              scopeChain_, type_, evalInFrame_);
+    return cx->runtime()->interpreterStack().pushExecuteFrame(cx, script_, thisv_, scopeChain_,
+                                                              type_, evalInFrame_);
 }
 namespace js {
 
 // Implementation of per-performance group performance measurement.
 //
 //
 // All mutable state is stored in `Runtime::stopwatch` (per-process
 // performance stats and logistics) and in `PerformanceGroup` (per
@@ -842,18 +842,17 @@ js::InvokeSetter(JSContext* cx, const Va
     JS_CHECK_RECURSION(cx, return false);
 
     RootedValue ignored(cx);
     return Invoke(cx, thisv, fval, 1, v.address(), &ignored);
 }
 
 bool
 js::ExecuteKernel(JSContext* cx, HandleScript script, JSObject& scopeChainArg, const Value& thisv,
-                  const Value& newTargetValue, ExecuteType type, AbstractFramePtr evalInFrame,
-                  Value* result)
+                  ExecuteType type, AbstractFramePtr evalInFrame, Value* result)
 {
     MOZ_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG);
     MOZ_ASSERT_IF(type == EXECUTE_GLOBAL, !IsSyntacticScope(&scopeChainArg));
 #ifdef DEBUG
     if (thisv.isObject()) {
         RootedObject thisObj(cx, &thisv.toObject());
         AutoSuppressGC nogc(cx);
         MOZ_ASSERT(GetOuterObject(cx, thisObj) == thisObj);
@@ -878,17 +877,17 @@ js::ExecuteKernel(JSContext* cx, HandleS
         if (result)
             result->setUndefined();
         return true;
     }
 
     TypeScript::SetThis(cx, script, thisv);
 
     probes::StartExecution(script);
-    ExecuteState state(cx, script, thisv, newTargetValue, scopeChainArg, type, evalInFrame, result);
+    ExecuteState state(cx, script, thisv, scopeChainArg, type, evalInFrame, result);
     bool ok = RunScript(cx, state);
     probes::StopExecution(script);
 
     return ok;
 }
 
 bool
 js::Execute(JSContext* cx, HandleScript script, JSObject& scopeChainArg, Value* rval)
@@ -918,17 +917,17 @@ js::Execute(JSContext* cx, HandleScript 
     }
 
     /* Use the scope chain as 'this', modulo outerization. */
     JSObject* thisObj = GetThisObject(cx, scopeChain);
     if (!thisObj)
         return false;
     Value thisv = ObjectValue(*thisObj);
 
-    return ExecuteKernel(cx, script, *scopeChain, thisv, NullValue(), EXECUTE_GLOBAL,
+    return ExecuteKernel(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL,
                          NullFramePtr() /* evalInFrame */, rval);
 }
 
 bool
 js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
 {
     const Class* clasp = obj->getClass();
     RootedValue local(cx, v);
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -100,18 +100,17 @@ InvokeConstructor(JSContext* cx, Value f
 /*
  * Executes a script with the given scopeChain/this. The 'type' indicates
  * whether this is eval code or global code. To support debugging, the
  * evalFrame parameter can point to an arbitrary frame in the context's call
  * stack to simulate executing an eval in that frame.
  */
 extern bool
 ExecuteKernel(JSContext* cx, HandleScript script, JSObject& scopeChain, const Value& thisv,
-              const Value& newTargetVal, ExecuteType type, AbstractFramePtr evalInFrame,
-              Value* result);
+              ExecuteType type, AbstractFramePtr evalInFrame, Value* result);
 
 /* Execute a script with the given scopeChain as global code. */
 extern bool
 Execute(JSContext* cx, HandleScript script, JSObject& scopeChain, Value* rval);
 
 class ExecuteState;
 class InvokeState;
 
@@ -159,38 +158,33 @@ class RunState
 };
 
 // Eval or global script.
 class ExecuteState : public RunState
 {
     ExecuteType type_;
 
     RootedValue thisv_;
-    RootedValue newTargetValue_;
     RootedObject scopeChain_;
 
     AbstractFramePtr evalInFrame_;
     Value* result_;
 
   public:
-    ExecuteState(JSContext* cx, JSScript* script, const Value& thisv, const Value& newTargetValue,
-                 JSObject& scopeChain, ExecuteType type, AbstractFramePtr evalInFrame,
-                 Value* result)
+    ExecuteState(JSContext* cx, JSScript* script, const Value& thisv, JSObject& scopeChain,
+                 ExecuteType type, AbstractFramePtr evalInFrame, Value* result)
       : RunState(cx, Execute, script),
         type_(type),
         thisv_(cx, thisv),
-        newTargetValue_(cx, newTargetValue),
         scopeChain_(cx, &scopeChain),
         evalInFrame_(evalInFrame),
         result_(result)
     { }
 
     Value* addressOfThisv() { return thisv_.address(); }
-    Value thisv() { return thisv_; }
-    Value newTarget() { return newTargetValue_; }
     JSObject* scopeChain() const { return scopeChain_; }
     ExecuteType type() const { return type_; }
 
     virtual InterpreterFrame* pushInterpreterFrame(JSContext* cx);
 
     virtual void setReturnValue(Value v) {
         if (result_)
             *result_ = v;
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -811,26 +811,16 @@ AbstractFramePtr::thisValue() const
 {
     if (isInterpreterFrame())
         return asInterpreterFrame()->thisValue();
     if (isBaselineFrame())
         return asBaselineFrame()->thisValue();
     return asRematerializedFrame()->thisValue();
 }
 
-inline Value
-AbstractFramePtr::newTarget() const
-{
-    if (isInterpreterFrame())
-        return asInterpreterFrame()->newTarget();
-    if (isBaselineFrame())
-        return asBaselineFrame()->newTarget();
-    return asRematerializedFrame()->newTarget();
-}
-
 inline bool
 AbstractFramePtr::freshenBlock(JSContext* cx) const
 {
     if (isInterpreterFrame())
         return asInterpreterFrame()->freshenBlock(cx);
     return asBaselineFrame()->freshenBlock(cx);
 }
 
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -28,73 +28,63 @@ using namespace js;
 
 using mozilla::Maybe;
 using mozilla::PodCopy;
 
 /*****************************************************************************/
 
 void
 InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractFramePtr evalInFramePrev,
-                                   const Value& thisv, const Value& newTargetValue, HandleObject scopeChain,
-                                   ExecuteType type)
+                                   const Value& thisv, HandleObject scopeChain, ExecuteType type)
 {
     /*
      * See encoding of ExecuteType. When GLOBAL isn't set, we are executing a
      * script in the context of another frame and the frame type is determined
      * by the context.
      */
     flags_ = type | HAS_SCOPECHAIN;
 
     JSObject* callee = nullptr;
-    RootedValue newTarget(cx, newTargetValue);
     if (!(flags_ & (GLOBAL))) {
         if (evalInFramePrev) {
             MOZ_ASSERT(evalInFramePrev.isFunctionFrame() || evalInFramePrev.isGlobalFrame());
             if (evalInFramePrev.isFunctionFrame()) {
                 callee = evalInFramePrev.callee();
-                if (newTarget.isNull())
-                    newTarget = evalInFramePrev.newTarget();
                 flags_ |= FUNCTION;
             } else {
                 flags_ |= GLOBAL;
             }
         } else {
             FrameIter iter(cx);
             MOZ_ASSERT(iter.isFunctionFrame() || iter.isGlobalFrame());
             MOZ_ASSERT(!iter.isAsmJS());
             if (iter.isFunctionFrame()) {
-                if (newTarget.isNull())
-                    newTarget = iter.newTarget();
                 callee = iter.callee(cx);
                 flags_ |= FUNCTION;
             } else {
                 flags_ |= GLOBAL;
             }
         }
     }
-    
-    // Null is just a sentinel value. We should have figured it out by now.
-    MOZ_ASSERT_IF(isFunctionFrame(), newTarget.isObject() || newTarget.isUndefined());
 
-    Value* dstvp = (Value*)this - 3;
-    dstvp[2] = thisv;
+    Value* dstvp = (Value*)this - 2;
+    dstvp[1] = thisv;
 
     if (isFunctionFrame()) {
-        dstvp[1] = ObjectValue(*callee);
+        dstvp[0] = ObjectValue(*callee);
         exec.fun = &callee->as<JSFunction>();
         u.evalScript = script;
     } else {
         MOZ_ASSERT(isGlobalFrame());
-        dstvp[1] = NullValue();
+        dstvp[0] = NullValue();
         exec.script = script;
 #ifdef DEBUG
         u.evalScript = (JSScript*)0xbad;
 #endif
     }
-    dstvp[0] = newTarget;
 
     scopeChain_ = scopeChain.get();
     prev_ = nullptr;
     prevpc_ = nullptr;
     prevsp_ = nullptr;
 
     MOZ_ASSERT_IF(evalInFramePrev, isDebuggerEvalFrame());
     evalInFramePrev_ = evalInFramePrev;
@@ -404,18 +394,18 @@ InterpreterFrame::markValues(JSTracer* t
         markValues(trc, 0, nlivefixed);
     }
 
     if (hasArgs()) {
         // Mark callee, |this| and arguments.
         unsigned argc = Max(numActualArgs(), numFormalArgs());
         TraceRootRange(trc, argc + 2 + isConstructing(), argv_ - 2, "fp argv");
     } else {
-        // Mark callee, |this|, and newTarget
-        TraceRootRange(trc, 3, ((Value*)this) - 3, "stack callee, this, newTarget");
+        // Mark callee and |this|
+        TraceRootRange(trc, 2, ((Value*)this) - 2, "stack callee and this");
     }
 }
 
 static void
 MarkInterpreterActivation(JSTracer* trc, InterpreterActivation* act)
 {
     for (InterpreterFrameIterator frames(act); !frames.done(); ++frames) {
         InterpreterFrame* fp = frames.frame();
@@ -463,29 +453,29 @@ InterpreterStack::pushInvokeFrame(JSCont
 
     fp->mark_ = mark;
     fp->initCallFrame(cx, nullptr, nullptr, nullptr, *fun, script, argv, args.length(), flags);
     return fp;
 }
 
 InterpreterFrame*
 InterpreterStack::pushExecuteFrame(JSContext* cx, HandleScript script, const Value& thisv,
-                                   const Value& newTargetValue, HandleObject scopeChain,
-                                   ExecuteType type, AbstractFramePtr evalInFrame)
+                                   HandleObject scopeChain, ExecuteType type,
+                                   AbstractFramePtr evalInFrame)
 {
     LifoAlloc::Mark mark = allocator_.mark();
 
-    unsigned nvars = 3 /* callee, this, newTarget */ + script->nslots();
+    unsigned nvars = 2 /* callee, this */ + script->nslots();
     uint8_t* buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvars * sizeof(Value));
     if (!buffer)
         return nullptr;
 
-    InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(buffer + 3 * sizeof(Value));
+    InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(buffer + 2 * sizeof(Value));
     fp->mark_ = mark;
-    fp->initExecuteFrame(cx, script, evalInFrame, thisv, newTargetValue, scopeChain, type);
+    fp->initExecuteFrame(cx, script, evalInFrame, thisv, scopeChain, type);
     fp->initLocals();
 
     return fp;
 }
 
 /*****************************************************************************/
 
 void
@@ -1258,32 +1248,16 @@ FrameIter::thisv(JSContext* cx) const
         return data_.jitFrames_.baselineFrame()->thisValue();
       case INTERP:
         return interpFrame()->thisValue();
     }
     MOZ_CRASH("Unexpected state");
 }
 
 Value
-FrameIter::newTarget() const
-{
-    switch (data_.state_) {
-      case DONE:
-      case ASMJS:
-        break;
-      case INTERP:
-        return interpFrame()->newTarget();
-      case JIT:
-        MOZ_ASSERT(data_.jitFrames_.isBaselineJS());
-        return data_.jitFrames_.baselineFrame()->newTarget();
-    }
-    MOZ_CRASH("Unexpected state");
-}
-
-Value
 FrameIter::returnValue() const
 {
     switch (data_.state_) {
       case DONE:
       case ASMJS:
         break;
       case JIT:
         if (data_.jitFrames_.isBaselineJS())
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -199,18 +199,16 @@ class AbstractFramePtr
 
     inline JSScript* script() const;
     inline JSFunction* fun() const;
     inline JSFunction* maybeFun() const;
     inline JSFunction* callee() const;
     inline Value calleev() const;
     inline Value& thisValue() const;
 
-    inline Value newTarget() const;
-
     inline bool isNonEvalFunctionFrame() const;
     inline bool isNonStrictDirectEvalFrame() const;
     inline bool isStrictEvalFrame() const;
 
     inline unsigned numActualArgs() const;
     inline unsigned numFormalArgs() const;
 
     inline Value* argv() const;
@@ -402,18 +400,17 @@ class InterpreterFrame
 
     /* Used for Invoke and Interpret. */
     void initCallFrame(JSContext* cx, InterpreterFrame* prev, jsbytecode* prevpc, Value* prevsp,
                        JSFunction& callee, JSScript* script, Value* argv, uint32_t nactual,
                        InterpreterFrame::Flags flags);
 
     /* Used for global and eval frames. */
     void initExecuteFrame(JSContext* cx, HandleScript script, AbstractFramePtr prev,
-                          const Value& thisv, const Value& newTargetValue,
-                          HandleObject scopeChain, ExecuteType type);
+                          const Value& thisv, HandleObject scopeChain, ExecuteType type);
 
   public:
     /*
      * Frame prologue/epilogue
      *
      * Every stack frame must have 'prologue' called before executing the
      * first op and 'epilogue' called after executing the last op and before
      * popping the frame (whether the exit is exceptional or not).
@@ -746,20 +743,18 @@ class InterpreterFrame
     /*
      * New Target
      *
      * Only function frames have a meaningful newTarget. An eval frame in a
      * function will have a copy of the newTarget of the enclosing function
      * frame.
      */
     Value newTarget() const {
-        MOZ_ASSERT(isFunctionFrame());
-        if (isEvalFrame())
-            return ((Value*)this)[-3];
-
+        // new.target in eval() NYI.
+        MOZ_ASSERT(isNonEvalFunctionFrame());
         if (isConstructing()) {
             unsigned pushedArgs = Max(numFormalArgs(), numActualArgs());
             return argv()[pushedArgs];
         }
         return UndefinedValue();
     }
 
     /*
@@ -1017,18 +1012,18 @@ class InterpreterStack
     { }
 
     ~InterpreterStack() {
         MOZ_ASSERT(frameCount_ == 0);
     }
 
     // For execution of eval or global code.
     InterpreterFrame* pushExecuteFrame(JSContext* cx, HandleScript script, const Value& thisv,
-                                 const Value& newTargetValue, HandleObject scopeChain,
-                                 ExecuteType type, AbstractFramePtr evalInFrame);
+                                 HandleObject scopeChain, ExecuteType type,
+                                 AbstractFramePtr evalInFrame);
 
     // Called to invoke a function.
     InterpreterFrame* pushInvokeFrame(JSContext* cx, const CallArgs& args,
                                       InitialFrameFlags initial);
 
     // The interpreter can push light-weight, "inline" frames without entering a
     // new InterpreterActivation or recursively calling Interpret.
     bool pushInlineFrame(JSContext* cx, InterpreterRegs& regs, const CallArgs& args,
@@ -1756,18 +1751,16 @@ class FrameIter
     // the Ion frame but is instead saved in the RematerializedFrame for use
     // by Debugger.
     //
     // Both methods exist because of speed. thisv() will never rematerialize
     // an Ion frame, whereas computedThisValue() will.
     Value       computedThisValue() const;
     Value       thisv(JSContext* cx) const;
 
-    Value       newTarget() const;
-
     Value       returnValue() const;
     void        setReturnValue(const Value& v);
 
     // These are only valid for the top frame.
     size_t      numFrameSlots() const;
     Value       frameSlotValue(size_t index) const;
 
     // Ensures that we have rematerialized the top frame and its associated