Backed out 7 changesets (bug 1141865) for assertion failures in various test suites CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Mon, 01 Jun 2015 18:25:38 -0700
changeset 246611 d245fc3d7b548cb82ed9909600439137132fe83e
parent 246610 7a6e1e804fab0c9b2f6072169f814156817c906e
child 246612 832e84b8380a452ed3ff0ecaddb67724c4aae1ef
child 246688 9eae3880b132898a96a80d497cba2b9523e049a4
push id60489
push userkwierso@gmail.com
push dateTue, 02 Jun 2015 01:26:47 +0000
treeherdermozilla-inbound@d245fc3d7b54 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1141865
milestone41.0a1
backs out3796a4c827e4644d7f49637e4c5441fa664aa4e8
41a10ac99656239298291dcb50f83d8e2e9306ae
027bba006fbb8e1605d157392cb61afd788e1c02
fc9d645f55b3e7f22bc344d564a455444dd1859e
6b87d4ed5d30650cc73e158db2418bc664df9dad
fcbf3e53cce6fd17535850a25ca5324387f37985
4a9a06c26be76782419cd145d096c72685ea0955
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 7 changesets (bug 1141865) for assertion failures in various test suites CLOSED TREE Backed out changeset 3796a4c827e4 (bug 1141865) Backed out changeset 41a10ac99656 (bug 1141865) Backed out changeset 027bba006fbb (bug 1141865) Backed out changeset fc9d645f55b3 (bug 1141865) Backed out changeset 6b87d4ed5d30 (bug 1141865) Backed out changeset fcbf3e53cce6 (bug 1141865) Backed out changeset 4a9a06c26be7 (bug 1141865)
js/public/CallArgs.h
js/src/builtin/Eval.cpp
js/src/builtin/Eval.h
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/FoldConstants.cpp
js/src/frontend/FullParseHandler.h
js/src/frontend/NameFunctions.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/SharedContext.h
js/src/frontend/SyntaxParseHandler.h
js/src/jit-test/tests/basic/newTargetOSR.js
js/src/jit-test/tests/basic/newTargetRectifier.js
js/src/jit-test/tests/debug/Frame-newTargetEval-01.js
js/src/jit-test/tests/debug/Frame-newTargetEval-02.js
js/src/jit-test/tests/debug/Frame-newTargetOverflow-01.js
js/src/jit-test/tests/proxy/testDirectProxyConstruct1.js
js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js
js/src/jit/BaselineBailouts.cpp
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
js/src/jit/BaselineFrame.cpp
js/src/jit/BaselineFrame.h
js/src/jit/BaselineFrameInfo.cpp
js/src/jit/BaselineFrameInfo.h
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
js/src/jit/BaselineJIT.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/Ion.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/JitCompartment.h
js/src/jit/JitFrameIterator.h
js/src/jit/JitFrames.cpp
js/src/jit/LIR-Common.h
js/src/jit/LOpcodes.h
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/jit/RematerializedFrame.cpp
js/src/jit/RematerializedFrame.h
js/src/jit/TypePolicy.cpp
js/src/jit/VMFunctions.cpp
js/src/jit/VMFunctions.h
js/src/jit/arm/Trampoline-arm.cpp
js/src/jit/x64/Trampoline-x64.cpp
js/src/jit/x86/Trampoline-x86.cpp
js/src/js.msg
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/testNewTargetInvokeConstructor.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsast.tbl
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsiter.cpp
js/src/jsopcode.cpp
js/src/jsreflect.cpp
js/src/proxy/CrossCompartmentWrapper.cpp
js/src/proxy/DirectProxyHandler.cpp
js/src/proxy/ScriptedDirectProxyHandler.cpp
js/src/proxy/ScriptedIndirectProxyHandler.cpp
js/src/tests/ecma_6/Class/newTargetArgumentsIntact.js
js/src/tests/ecma_6/Class/newTargetArrow.js
js/src/tests/ecma_6/Class/newTargetBound.js
js/src/tests/ecma_6/Class/newTargetCCW.js
js/src/tests/ecma_6/Class/newTargetDVG.js
js/src/tests/ecma_6/Class/newTargetDirectInvoke.js
js/src/tests/ecma_6/Class/newTargetEval.js
js/src/tests/ecma_6/Class/newTargetGenerators.js
js/src/tests/ecma_6/Class/newTargetMethods.js
js/src/tests/ecma_6/Class/shell.js
js/src/tests/ecma_6/Class/superPropDVG.js
js/src/tests/js1_7/extensions/regress-354945-01.js
js/src/tests/js1_7/extensions/regress-354945-02.js
js/src/tests/js1_8_5/reflect-parse/PatternAsserts.js
js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js
js/src/tests/js1_8_5/reflect-parse/newTarget.js
js/src/vm/CommonPropertyNames.h
js/src/vm/Debugger.cpp
js/src/vm/GeneratorObject.cpp
js/src/vm/GeneratorObject.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
js/src/vm/Opcodes.h
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/Xdr.h
--- a/js/public/CallArgs.h
+++ b/js/public/CallArgs.h
@@ -280,17 +280,16 @@ namespace detail {
 template<UsedRval WantUsedRval>
 class MOZ_STACK_CLASS CallArgsBase :
         public mozilla::Conditional<WantUsedRval == detail::IncludeUsedRval,
                                     CallReceiver,
                                     CallReceiverBase<NoUsedRval> >::Type
 {
   protected:
     unsigned argc_;
-    bool constructing_;
 
   public:
     /* Returns the number of arguments. */
     unsigned length() const { return argc_; }
 
     /* Returns the i-th zero-indexed argument. */
     MutableHandleValue operator[](unsigned i) const {
         MOZ_ASSERT(i < argc_);
@@ -310,69 +309,63 @@ class MOZ_STACK_CLASS CallArgsBase :
     /*
      * Returns true if the i-th zero-indexed argument is present and is not
      * |undefined|.
      */
     bool hasDefined(unsigned i) const {
         return i < argc_ && !this->argv_[i].isUndefined();
     }
 
-    MutableHandleValue newTarget() const {
-        MOZ_ASSERT(constructing_);
-        return MutableHandleValue::fromMarkedLocation(&this->argv_[argc_]);
-    }
-
   public:
     // These methods are publicly exposed, but we're less sure of the interface
     // here than we'd like (because they're hackish and drop assertions).  Try
     // to avoid using these if you can.
 
     Value* array() const { return this->argv_; }
-    Value* end() const { return this->argv_ + argc_ + constructing_; }
+    Value* end() const { return this->argv_ + argc_; }
 };
 
 } // namespace detail
 
 class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase<detail::IncludeUsedRval>
 {
   private:
     friend CallArgs CallArgsFromVp(unsigned argc, Value* vp);
-    friend CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing);
+    friend CallArgs CallArgsFromSp(unsigned argc, Value* sp);
 
-    static CallArgs create(unsigned argc, Value* argv, bool constructing) {
+    static CallArgs create(unsigned argc, Value* argv) {
         CallArgs args;
         args.clearUsedRval();
         args.argv_ = argv;
         args.argc_ = argc;
-        args.constructing_ = constructing;
         return args;
     }
 
   public:
     /*
      * Returns true if there are at least |required| arguments passed in. If
      * false, it reports an error message on the context.
      */
     bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required);
 
 };
 
 MOZ_ALWAYS_INLINE CallArgs
 CallArgsFromVp(unsigned argc, Value* vp)
 {
-    return CallArgs::create(argc, vp + 2, vp[1].isMagic(JS_IS_CONSTRUCTING));
+    return CallArgs::create(argc, vp + 2);
 }
 
 // This method is only intended for internal use in SpiderMonkey.  We may
 // eventually move it to an internal header.  Embedders should use
 // JS::CallArgsFromVp!
 MOZ_ALWAYS_INLINE CallArgs
-CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing = false)
+CallArgsFromSp(unsigned argc, Value* sp)
 {
-    return CallArgs::create(stackSlots - constructing, sp - stackSlots, constructing);
+    return CallArgs::create(argc, sp - argc);
 }
 
 } // namespace JS
 
 /*
  * Macros to hide interpreter stack layout details from a JSNative using its
  * JS::Value* vp parameter.  DO NOT USE THESE!  Instead use JS::CallArgs and
  * friends, above.  These macros will be removed when we change JSNative to
--- 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,34 @@ 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::DirectEvalValueFromIon(JSContext* cx,
+                           HandleObject scopeobj, HandleScript callerScript,
+                           HandleValue thisValue, HandleValue evalArg,
+                           jsbytecode* pc, MutableHandleValue vp)
+{
+    // Act as identity on non-strings per ES5 15.1.2.1 step 1.
+    if (!evalArg.isString()) {
+        vp.set(evalArg);
+        return true;
+    }
+
+    RootedString string(cx, evalArg.toString());
+    return DirectEvalStringFromIon(cx, scopeobj, callerScript, thisValue, string, pc, vp);
 }
 
 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 +545,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,22 @@ 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);
+extern bool
+DirectEvalValueFromIon(JSContext* cx,
+                       HandleObject scopeObj, HandleScript callerScript,
+                       HandleValue thisValue, HandleValue evalArg,
+                       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/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5451,29 +5451,16 @@ BytecodeEmitter::emitFor(ParseNode* pn, 
 
     if (pn->pn_left->isKind(PNK_FOROF))
         return emitForOf(STMT_FOR_OF_LOOP, pn, top);
 
     MOZ_ASSERT(pn->pn_left->isKind(PNK_FORHEAD));
     return emitNormalFor(pn, top);
 }
 
-bool
-BytecodeEmitter::arrowNeedsNewTarget()
-{
-    for (BytecodeEmitter* bce = this; bce; bce = bce->parent) {
-        SharedContext *sc = bce->sc;
-        if (sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow())
-            continue;
-
-        return sc->allowSyntax(SharedContext::AllowedSyntax::NewTarget);
-    }
-    MOZ_CRASH("impossible parent chain");
-}
-
 MOZ_NEVER_INLINE bool
 BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
 {
     FunctionBox* funbox = pn->pn_funbox;
     RootedFunction fun(cx, funbox->function());
     MOZ_ASSERT_IF(fun->isInterpretedLazy(), fun->lazyScript());
 
     /*
@@ -5555,31 +5542,20 @@ BytecodeEmitter::emitFunction(ParseNode*
         MOZ_ASSERT(IsAsmJSModuleNative(fun->native()));
     }
 
     /* Make the function object a literal in the outer script's pool. */
     unsigned index = objectList.add(pn->pn_funbox);
 
     /* Non-hoisted functions simply emit their respective op. */
     if (!pn->functionIsHoisted()) {
-        /* JSOP_LAMBDA_ARROW is always preceded by JSOP_THIS and a new.target */
+        /* JSOP_LAMBDA_ARROW is always preceded by JSOP_THIS. */
         MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW));
-        if (fun->isArrow()) {
-            if (!emit1(JSOP_THIS))
-                return false;
-
-            if (arrowNeedsNewTarget()) {
-                if (!emit1(JSOP_NEWTARGET))
-                    return false;
-            } else {
-                if (!emit1(JSOP_NULL))
-                    return false;
-            }
-        }
-
+        if (fun->isArrow() && !emit1(JSOP_THIS))
+            return false;
         if (needsProto) {
             MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
             pn->setOp(JSOP_FUNWITHPROTO);
         }
         return emitIndex32(pn->getOp(), index);
     }
 
     MOZ_ASSERT(!needsProto);
@@ -6442,44 +6418,31 @@ BytecodeEmitter::emitCallOrNew(ParseNode
         break;
     }
     if (!callop) {
         JSOp thisop = pn->isKind(PNK_GENEXP) ? JSOP_THIS : JSOP_UNDEFINED;
         if (!emit1(thisop))
             return false;
     }
 
-    bool isNewOp = pn->getOp() == JSOP_NEW || pn->getOp() == JSOP_SPREADNEW;
-
     /*
      * Emit code for each argument in order, then emit the JSOP_*CALL or
      * JSOP_NEW bytecode with a two-byte immediate telling how many args
      * were pushed on the operand stack.
      */
     bool oldEmittingForInit = emittingForInit;
     emittingForInit = false;
     if (!spread) {
         for (ParseNode* pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
             if (!emitTree(pn3))
                 return false;
         }
-
-        if (isNewOp) {
-            // Repush the callee as new.target
-            if (!emitDupAt(this->stackDepth - 1 - (argc + 1)))
-                return false;
-        }
     } else {
         if (!emitArray(pn2->pn_next, argc, JSOP_SPREADCALLARRAY))
             return false;
-
-        if (isNewOp) {
-            if (!emitDupAt(this->stackDepth - 1 - 2))
-                return false;
-        }
     }
     emittingForInit = oldEmittingForInit;
 
     if (!spread) {
         if (!emitCall(pn->getOp(), argc, pn))
             return false;
     } else {
         if (!emit1(pn->getOp()))
@@ -7655,21 +7618,16 @@ BytecodeEmitter::emitTree(ParseNode* pn)
       case PNK_NOP:
         MOZ_ASSERT(pn->getArity() == PN_NULLARY);
         break;
 
       case PNK_CLASS:
         ok = emitClass(pn);
         break;
 
-      case PNK_NEWTARGET:
-        if (!emit1(JSOP_NEWTARGET))
-            return false;
-        break;
-
       default:
         MOZ_ASSERT(0);
     }
 
     /* bce->emitLevel == 1 means we're last on the stack, so finish up. */
     if (ok && emitLevel == 1) {
         if (!updateSourceCoordNotes(pn->pn_pos.end))
             return false;
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -427,17 +427,16 @@ struct BytecodeEmitter
     bool emitArray(ParseNode* pn, uint32_t count, JSOp op);
     bool emitArrayComp(ParseNode* pn);
 
     bool emitInternedObjectOp(uint32_t index, JSOp op);
     bool emitObjectOp(ObjectBox* objbox, JSOp op);
     bool emitObjectPairOp(ObjectBox* objbox1, ObjectBox* objbox2, JSOp op);
     bool emitRegExp(uint32_t index);
 
-    bool arrowNeedsNewTarget();
     MOZ_NEVER_INLINE bool emitFunction(ParseNode* pn, bool needsProto = false);
     MOZ_NEVER_INLINE bool emitObject(ParseNode* pn);
 
     bool emitPropertyList(ParseNode* pn, MutableHandlePlainObject objp, PropListType type);
 
     // To catch accidental misuse, emitUint16Operand/emit3 assert that they are
     // not used to unconditionally emit JSOP_GETLOCAL. Variable access should
     // instead be emitted using EmitVarOp. In special cases, when the caller
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -397,17 +397,16 @@ ContainsHoistedDeclaration(ExclusiveCont
       case PNK_FOROF:
       case PNK_FORHEAD:
       case PNK_FRESHENBLOCK:
       case PNK_CLASSMETHOD:
       case PNK_CLASSMETHODLIST:
       case PNK_CLASSNAMES:
       case PNK_SUPERPROP:
       case PNK_SUPERELEM:
-      case PNK_NEWTARGET:
         MOZ_CRASH("ContainsHoistedDeclaration should have indicated false on "
                   "some parent node without recurring to test this node");
 
       case PNK_GLOBALCONST:
         MOZ_CRASH("ContainsHoistedDeclaration is only called on nested nodes where "
                   "globalconst nodes should never have been generated");
 
       case PNK_LIMIT: // invalid sentinel value
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -294,19 +294,16 @@ class FullParseHandler
         return new_<ClassNames>(outer, inner, pos);
     }
     ParseNode* newSuperProperty(JSAtom* atom, const TokenPos& pos) {
         return new_<SuperProperty>(atom, pos);
     }
     ParseNode* newSuperElement(ParseNode* expr, const TokenPos& pos) {
         return new_<SuperElement>(expr, pos);
     }
-    ParseNode* newNewTarget(const TokenPos& pos) {
-        return new_<NullaryNode>(PNK_NEWTARGET, pos);
-    }
 
     bool addPrototypeMutation(ParseNode* literal, uint32_t begin, ParseNode* expr) {
         // Object literals with mutated [[Prototype]] are non-constant so that
         // singleton objects will have Object.prototype as their [[Prototype]].
         setListFlag(literal, PNX_NONCONST);
 
         ParseNode* mutation = newUnary(PNK_MUTATEPROTO, JSOP_NOP, begin, expr);
         if (!mutation)
@@ -669,19 +666,16 @@ class FullParseHandler
     TokenPos getPosition(ParseNode* pn) {
         return pn->pn_pos;
     }
 
     ParseNode* newList(ParseNodeKind kind, JSOp op = JSOP_NOP) {
         MOZ_ASSERT(kind != PNK_VAR);
         return new_<ListNode>(kind, op, pos());
     }
-    ParseNode* newList(ParseNodeKind kind, uint32_t begin, JSOp op = JSOP_NOP) {
-        return new_<ListNode>(kind, op, TokenPos(begin, begin + 1));
-    }
     ParseNode* newDeclarationList(ParseNodeKind kind, JSOp op = JSOP_NOP) {
         MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET ||
                    kind == PNK_GLOBALCONST);
         return new_<ListNode>(kind, op, pos());
     }
 
     /* New list with one initial child node. kid must be non-null. */
     ParseNode* newList(ParseNodeKind kind, ParseNode* kid, JSOp op = JSOP_NOP) {
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -369,17 +369,16 @@ class NameResolver
           case PNK_NUMBER:
           case PNK_BREAK:
           case PNK_CONTINUE:
           case PNK_DEBUGGER:
           case PNK_EXPORT_BATCH_SPEC:
           case PNK_FRESHENBLOCK:
           case PNK_SUPERPROP:
           case PNK_OBJECT_PROPERTY_NAME:
-          case PNK_NEWTARGET:
             MOZ_ASSERT(cur->isArity(PN_NULLARY));
             break;
 
           // Nodes with a single non-null child requiring name resolution.
           case PNK_TYPEOF:
           case PNK_VOID:
           case PNK_NOT:
           case PNK_BITNOT:
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -210,17 +210,16 @@ PushNodeChildren(ParseNode* pn, NodeStac
       case PNK_NUMBER:
       case PNK_BREAK:
       case PNK_CONTINUE:
       case PNK_DEBUGGER:
       case PNK_EXPORT_BATCH_SPEC:
       case PNK_OBJECT_PROPERTY_NAME:
       case PNK_FRESHENBLOCK:
       case PNK_SUPERPROP:
-      case PNK_NEWTARGET:
         MOZ_ASSERT(pn->isArity(PN_NULLARY));
         MOZ_ASSERT(!pn->isUsed(), "handle non-trivial cases separately");
         MOZ_ASSERT(!pn->isDefn(), "handle non-trivial cases separately");
         return PushResult::Recyclable;
 
       // Nodes with a single non-null child.
       case PNK_TYPEOF:
       case PNK_VOID:
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -150,17 +150,16 @@ class UpvarCookie
     F(SPREAD) \
     F(MUTATEPROTO) \
     F(CLASS) \
     F(CLASSMETHOD) \
     F(CLASSMETHODLIST) \
     F(CLASSNAMES) \
     F(SUPERPROP) \
     F(SUPERELEM) \
-    F(NEWTARGET) \
     \
     /* Unary operators. */ \
     F(TYPEOF) \
     F(VOID) \
     F(NOT) \
     F(BITNOT) \
     \
     /* \
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7797,45 +7797,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())
-            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)
@@ -7846,46 +7829,37 @@ Parser<ParseHandler>::memberExpr(YieldHa
 
     JS_CHECK_RECURSION(context, return null());
 
     bool isSuper = false;
     uint32_t superBegin = pos().begin;
 
     /* Check for new expression first. */
     if (tt == TOK_NEW) {
-        uint32_t newBegin = pos().begin;
-        // Make sure this wasn't a |new.target| in disguise.
-        Node newTarget;
-        if (!tryNewTarget(newTarget))
-            return null();
-        if (newTarget) {
-            lhs = newTarget;
-        } else {
-            lhs = handler.newList(PNK_NEW, newBegin, JSOP_NEW);
-            if (!lhs)
+        lhs = handler.newList(PNK_NEW, JSOP_NEW);
+        if (!lhs)
+            return null();
+
+        if (!tokenStream.getToken(&tt, TokenStream::Operand))
+            return null();
+        Node ctorExpr = memberExpr(yieldHandling, tt, false, PredictInvoked);
+        if (!ctorExpr)
+            return null();
+
+        handler.addList(lhs, ctorExpr);
+
+        bool matched;
+        if (!tokenStream.matchToken(&matched, TOK_LP))
+            return null();
+        if (matched) {
+            bool isSpread = false;
+            if (!argumentList(yieldHandling, lhs, &isSpread))
                 return null();
-
-            // Gotten by tryNewTarget
-            tt = tokenStream.currentToken().type;
-            Node ctorExpr = memberExpr(yieldHandling, tt, false, PredictInvoked);
-            if (!ctorExpr)
-                return null();
-
-            handler.addList(lhs, ctorExpr);
-
-            bool matched;
-            if (!tokenStream.matchToken(&matched, TOK_LP))
-                return null();
-            if (matched) {
-                bool isSpread = false;
-                if (!argumentList(yieldHandling, lhs, &isSpread))
-                    return null();
-                if (isSpread)
-                    handler.setOp(lhs, JSOP_SPREADNEW);
-            }
+            if (isSpread)
+                handler.setOp(lhs, JSOP_SPREADNEW);
         }
     } else if (tt == TOK_SUPER) {
         lhs = null();
         isSuper = true;
     } else {
         lhs = primaryExpr(yieldHandling, tt, invoked);
         if (!lhs)
             return null();
@@ -8595,52 +8569,16 @@ Parser<ParseHandler>::methodDefinition(Y
     if (listType == ClassBody)
         return handler.addClassMethodDefinition(propList, propname, fn, op, isStatic);
 
     MOZ_ASSERT(listType == ObjectLiteral);
     return handler.addObjectMethodDefinition(propList, propname, fn, op);
 }
 
 template <typename ParseHandler>
-bool
-Parser<ParseHandler>::tryNewTarget(Node &newTarget)
-{
-    MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_NEW));
-
-    uint32_t begin = pos().begin;
-    newTarget = null();
-
-    // |new| expects to look for an operand, so we will honor that.
-    TokenKind next;
-    if (!tokenStream.getToken(&next, TokenStream::Operand))
-        return false;
-
-    // Don't unget the token, since lookahead cannot handle someone calling
-    // getToken() with a different modifier. Callers should inspect currentToken().
-    if (next != TOK_DOT)
-        return true;
-
-    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)) {
-        reportWithOffset(ParseError, false, begin, JSMSG_BAD_NEWTARGET);
-        return false;
-    }
-
-    newTarget = handler.newNewTarget(TokenPos(begin, pos().end));
-    return !!newTarget;
-}
-
-template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TokenKind tt,
                                   InvokedPrediction invoked)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
     JS_CHECK_RECURSION(context, return null());
 
     switch (tt) {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -584,19 +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);
 
     /*
      * Additional JS parsers.
--- 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:
-            // Any function supports new.target
-            return true;
-          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,23 +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 &&
                 !it.fun().isArrow())
             {
-                return FunctionAllowsSyntax(&it.fun(), allowed);
+                return it.fun().allowSuperProperty();
             }
         }
         return false;
     }
 };
 
 class FunctionBox : public ObjectBox, public SharedContext
 {
@@ -335,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
@@ -367,18 +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 {
-        return FunctionAllowsSyntax(function(), allowed);
+    bool allowSuperProperty() const {
+        return function()->allowSuperProperty();
     }
 };
 
 inline FunctionBox*
 SharedContext::asFunctionBox()
 {
     MOZ_ASSERT(isFunctionBox());
     return static_cast<FunctionBox*>(this);
@@ -386,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()
 {
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -188,17 +188,16 @@ class SyntaxParseHandler
     bool addElision(Node literal, const TokenPos& pos) { return true; }
     bool addSpreadElement(Node literal, uint32_t begin, Node inner) { return true; }
     void addArrayElement(Node literal, Node element) { }
 
     Node newObjectLiteral(uint32_t begin) { return NodeGeneric; }
     Node newClassMethodList(uint32_t begin) { return NodeGeneric; }
     Node newSuperProperty(JSAtom* atom, const TokenPos& pos) { return NodeGeneric; }
     Node newSuperElement(Node expr, const TokenPos& pos) { return NodeGeneric; }
-    Node newNewTarget(const TokenPos& pos) { return NodeGeneric; }
     bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
     bool addPropertyDefinition(Node literal, Node name, Node expr) { return true; }
     bool addShorthand(Node literal, Node name, Node expr) { return true; }
     bool addObjectMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
     bool addClassMethodDefinition(Node literal, Node name, Node fn, JSOp op, bool isStatic) { return true; }
     Node newYieldExpression(uint32_t begin, Node value, Node gen) { return NodeUnparenthesizedYieldExpr; }
     Node newYieldStarExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
 
@@ -277,19 +276,16 @@ class SyntaxParseHandler
     TokenPos getPosition(Node pn) {
         return tokenStream.currentToken().pos;
     }
 
     Node newList(ParseNodeKind kind, JSOp op = JSOP_NOP) {
         MOZ_ASSERT(kind != PNK_VAR);
         return NodeGeneric;
     }
-    Node newList(ParseNodeKind kind, uint32_t begin, JSOp op = JSOP_NOP) {
-        return NodeGeneric;
-    }
     Node newDeclarationList(ParseNodeKind kind, JSOp op = JSOP_NOP) {
         MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET ||
                    kind == PNK_GLOBALCONST);
         return kind == PNK_VAR ? NodeHoistableDeclaration : NodeGeneric;
     }
     Node newList(ParseNodeKind kind, Node kid, JSOp op = JSOP_NOP) {
         MOZ_ASSERT(kind != PNK_VAR);
         return NodeGeneric;
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/newTargetOSR.js
+++ /dev/null
@@ -1,6 +0,0 @@
-function testOSRNewTarget(expected) {
-    for (let i = 0; i < 1100; i++)
-        assertEq(new.target, expected);
-}
-
-new testOSRNewTarget(testOSRNewTarget);
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/newTargetRectifier.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function testBailoutNewTarget() {
-    function Inner(ex, forceRectifier) {
-        bailout();
-        assertEq(new.target, ex);
-    }
-
-    for (let i = 0; i < 1100; i++)
-        new Inner(Inner);
-}
-
-for (let i = 0; i < 15; i++)
-    testBailoutNewTarget();
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);
-  } + ")();");
-});
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/Frame-newTargetEval-02.js
+++ /dev/null
@@ -1,41 +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");
-
-      // the arrow function will not be constructing, even though it has a
-      // new.target value.
-      assertEq(frame.constructing, false);
-
-      // 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').return.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);
-  } + ")();");
-});
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/Frame-newTargetOverflow-01.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Test that Ion frames are invalidated by turning on Debugger. Invalidation
-// is unobservable, but we know that Ion scripts cannot handle Debugger
-// handlers, so we test for the handlers being called.
-
-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) {
-    if (d) {
-      dbg.addDebuggee(g);
-
-      var frame = dbg.getNewestFrame();
-      assertEq(frame.implementation, "ion");
-      assertEq(frame.constructing, true);
-
-      // overflow args are read from the parent's frame
-      // ensure we have the right offset to read from those.
-      assertEq(frame.arguments[1], 15);
-    }
-  };
-
-  g.eval("" + function f(d) { new g(d, 15); });
-
-  g.eval("" + function g(d) { toggle(d); });
-
-  g.eval("(" + function test() {
-    for (var i = 0; i < 5; i++)
-      f(false);
-    f(true);
-  } + ")();");
-});
--- a/js/src/jit-test/tests/proxy/testDirectProxyConstruct1.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyConstruct1.js
@@ -1,12 +1,10 @@
 // Forward to the target if the trap is undefined
-var p;
 var target = function (x, y) {
-    assertEq(new.target, p);
     this.foo = x + y;
 }
 
-for (p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
+for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
     var obj = new p(2, 3);
     assertEq(obj.foo, 5);
     assertEq(Object.getPrototypeOf(obj), target.prototype);
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js
@@ -1,21 +1,19 @@
 load(libdir + "asserts.js");
 /*
  * Call the trap with the handler as the this value, the target as the first
  * argument, and the original arguments as the third argument.
  *
  * Hooks that don't return an object must throw.
  */
-var p;
 var target = function () {};
 var handler = {
-    construct: function (target1, args, newTarget) {
+    construct: function (target1, args) {
         assertEq(this, handler);
         assertEq(target1, target);
         assertEq(args.length, 2);
         assertEq(args[0], 2);
         assertEq(args[1], 3);
-        assertEq(newTarget, p);
     }
 }
-for (p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
+for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
     assertThrowsInstanceOf(function () {new p(2, 3)}, TypeError);
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -449,17 +449,17 @@ static inline void*
 GetStubReturnAddress(JSContext* cx, jsbytecode* pc)
 {
     if (IsGetPropPC(pc))
         return cx->compartment()->jitCompartment()->baselineGetPropReturnAddr();
     if (IsSetPropPC(pc))
         return cx->compartment()->jitCompartment()->baselineSetPropReturnAddr();
     // This should be a call op of some kind, now.
     MOZ_ASSERT(IsCallPC(pc));
-    return cx->compartment()->jitCompartment()->baselineCallReturnAddr(JSOp(*pc) == JSOP_NEW);
+    return cx->compartment()->jitCompartment()->baselineCallReturnAddr();
 }
 
 static inline jsbytecode*
 GetNextNonLoopEntryPc(jsbytecode* pc)
 {
     JSOp op = JSOp(*pc);
     if (op == JSOP_GOTO)
         return pc + GET_JUMP_OFFSET(pc);
@@ -971,18 +971,16 @@ InitFromBailout(JSContext* cx, HandleScr
 
     JitSpew(JitSpew_BaselineBailouts, "      Resuming %s pc offset %d (op %s) (line %d) of %s:%" PRIuSIZE,
                 resumeAfter ? "after" : "at", (int) pcOff, js_CodeName[op],
                 PCToLineNumber(script, pc), script->filename(), script->lineno());
     JitSpew(JitSpew_BaselineBailouts, "      Bailout kind: %s",
             BailoutKindString(bailoutKind));
 #endif
 
-    bool pushedNewTarget = op == JSOP_NEW;
-    
     // If this was the last inline frame, or we are bailing out to a catch or
     // finally block in this frame, then unpacking is almost done.
     if (!iter.moreFrames() || catchingException) {
         // Last frame, so PC for call to next frame is set to nullptr.
         *callPC = nullptr;
 
         // If the bailout was a resumeAfter, and the opcode is monitored,
         // then the bailed out state should be in a position to enter
@@ -1029,24 +1027,21 @@ InitFromBailout(JSContext* cx, HandleScr
             // stack and pops them only after returning from the call IC.
             // Push undefs onto the stack in anticipation of the popping of the
             // callee, thisv, and actual arguments passed from the caller's frame.
             if (isCall) {
                 builder.writeValue(UndefinedValue(), "CallOp FillerCallee");
                 builder.writeValue(UndefinedValue(), "CallOp FillerThis");
                 for (uint32_t i = 0; i < numCallArgs; i++)
                     builder.writeValue(UndefinedValue(), "CallOp FillerArg");
-                if (pushedNewTarget)
-                    builder.writeValue(UndefinedValue(), "CallOp FillerNewTarget");
 
-                frameSize += (numCallArgs + 2 + pushedNewTarget) * sizeof(Value);
+                frameSize += (numCallArgs + 2) * sizeof(Value);
                 blFrame->setFrameSize(frameSize);
                 JitSpew(JitSpew_BaselineBailouts, "      Adjusted framesize += %d: %d",
-                                (int) ((numCallArgs + 2 + pushedNewTarget) * sizeof(Value)),
-                                (int) frameSize);
+                                (int) ((numCallArgs + 2) * sizeof(Value)), (int) frameSize);
             }
 
             // Set the resume address to the return point from the IC, and set
             // the monitor stub addr.
             builder.setResumeAddr(baselineScript->returnAddressForIC(icEntry));
             builder.setMonitorStub(firstMonStub);
             JitSpew(JitSpew_BaselineBailouts, "      Set resumeAddr=%p monitorStub=%p",
                     baselineScript->returnAddressForIC(icEntry), firstMonStub);
@@ -1228,23 +1223,22 @@ InitFromBailout(JSContext* cx, HandleScr
     } else {
         actualArgc = GET_ARGC(pc);
         if (op == JSOP_FUNCALL) {
             MOZ_ASSERT(actualArgc > 0);
             actualArgc--;
         }
 
         // Align the stack based on the number of arguments.
-        size_t afterFrameSize = (actualArgc + 1 + pushedNewTarget) * sizeof(Value) +
-                                JitFrameLayout::Size();
+        size_t afterFrameSize = (actualArgc + 1) * sizeof(Value) + JitFrameLayout::Size();
         if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding"))
             return false;
 
-        MOZ_ASSERT(actualArgc + 2 + pushedNewTarget <= exprStackSlots);
-        for (unsigned i = 0; i < actualArgc + 1 + pushedNewTarget; i++) {
+        MOZ_ASSERT(actualArgc + 2 <= exprStackSlots);
+        for (unsigned i = 0; i < actualArgc + 1; i++) {
             size_t argSlot = (script->nfixed() + exprStackSlots) - (i + 1);
             if (!builder.writeValue(*blFrame->valueSlot(argSlot), "ArgVal"))
                 return false;
         }
     }
 
     // In case these arguments need to be copied on the stack again for a rectifier frame,
     // save the framePushed values here for later use.
@@ -1261,17 +1255,17 @@ InitFromBailout(JSContext* cx, HandleScr
 
     // Push callee token (must be a JS Function)
     Value callee;
     if (needToSaveArgs) {
         // The arguments of FUNAPPLY or inlined accessors are not writen to the stack.
         // So get the callee from the specially saved vector.
         callee = savedCallerArgs[0];
     } else {
-        uint32_t calleeStackSlot = exprStackSlots - uint32_t(actualArgc + 2 + pushedNewTarget);
+        uint32_t calleeStackSlot = exprStackSlots - uint32_t(actualArgc + 2);
         size_t calleeOffset = (builder.framePushed() - endOfBaselineJSFrameStack)
             + ((exprStackSlots - (calleeStackSlot + 1)) * sizeof(Value));
         callee = *builder.valuePointerAtStackOffset(calleeOffset);
         JitSpew(JitSpew_BaselineBailouts, "      CalleeStackSlot=%d", (int) calleeStackSlot);
     }
     JitSpew(JitSpew_BaselineBailouts, "      Callee = %016llx", *((uint64_t*) &callee));
     MOZ_ASSERT(callee.isObject() && callee.toObject().is<JSFunction>());
     JSFunction* calleeFun = &callee.toObject().as<JSFunction>();
@@ -1332,28 +1326,20 @@ InitFromBailout(JSContext* cx, HandleScr
         return false;
     // Follow the same logic as in JitRuntime::generateArgumentsRectifier.
     prevFramePtr = builder.virtualPointerAtStackOffset(0);
     if (!builder.writePtr(prevFramePtr, "Padding-X86Only"))
         return false;
 #endif
 
     // Align the stack based on the number of arguments.
-    size_t afterFrameSize = (calleeFun->nargs() + 1 + pushedNewTarget) * sizeof(Value) +
-                            RectifierFrameLayout::Size();
+    size_t afterFrameSize = (calleeFun->nargs() + 1) * sizeof(Value) + RectifierFrameLayout::Size();
     if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding"))
         return false;
 
-    // Copy new.target, if necessary.
-    if (pushedNewTarget) {
-        size_t newTargetOffset = (builder.framePushed() - endOfBaselineStubArgs) +
-                                 (actualArgc + 1) * sizeof(Value);
-        builder.writeValue(*builder.valuePointerAtStackOffset(newTargetOffset), "CopiedNewTarget");
-    }
-
     // Push undefined for missing arguments.
     for (unsigned i = 0; i < (calleeFun->nargs() - actualArgc); i++) {
         if (!builder.writeValue(UndefinedValue(), "FillerVal"))
             return false;
     }
 
     // Copy arguments + thisv from BaselineStub frame.
     if (!builder.subtract((actualArgc + 1) * sizeof(Value), "CopiedArgs"))
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1458,34 +1458,32 @@ BaselineCompiler::emit_JSOP_LAMBDA()
         return false;
 
     // Box and push return value.
     masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
     frame.push(R0);
     return true;
 }
 
-typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject,
-                                   HandleValue, HandleValue);
+typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, HandleValue);
 static const VMFunction LambdaArrowInfo = FunctionInfo<LambdaArrowFn>(js::LambdaArrow);
 
 bool
 BaselineCompiler::emit_JSOP_LAMBDA_ARROW()
 {
-    // Keep pushed |this| in R0, and newTarget in R1.
-    frame.popRegsAndSync(2);
+    // Keep pushed |this| in R0.
+    frame.popRegsAndSync(1);
 
     RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
 
     prepareVMCall();
-    masm.loadPtr(frame.addressOfScopeChain(), R2.scratchReg());
-
-    pushArg(R1);
+    masm.loadPtr(frame.addressOfScopeChain(), R1.scratchReg());
+
     pushArg(R0);
-    pushArg(R2.scratchReg());
+    pushArg(R1.scratchReg());
     pushArg(ImmGCPtr(fun));
 
     if (!callVM(LambdaArrowInfo))
         return false;
 
     // Box and push return value.
     masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
     frame.push(R0);
@@ -1510,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");
     }
 }
@@ -2680,68 +2673,16 @@ BaselineCompiler::emit_JSOP_SETARG()
         script->setUninlineable();
 
     modifiesArguments_ = true;
 
     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 (function()->isArrow()) {
-        // Arrow functions store their |new.target| value in an
-        // extended slot.
-        Register scratch = R0.scratchReg();
-        masm.loadFunctionFromCalleeToken(frame.addressOfCalleeToken(), scratch);
-        masm.loadValue(Address(scratch, FunctionExtended::offsetOfArrowNewTargetSlot()), R0);
-        frame.push(R0);
-        return true;
-    }
-
-    // if (!isConstructing()) push(undefined)
-    Label constructing, done;
-    masm.branchTestPtr(Assembler::NonZero, frame.addressOfCalleeToken(),
-                       Imm32(CalleeToken_FunctionConstructing), &constructing);
-    masm.moveValue(UndefinedValue(), R0);
-    masm.jump(&done);
-
-    masm.bind(&constructing);
-
-    // else push(argv[Max(numActualArgs, numFormalArgs)])
-    Register argvLen = R0.scratchReg();
-
-    Address actualArgs(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs());
-    masm.loadPtr(actualArgs, argvLen);
-
-    Label actualArgsSufficient;
-
-    masm.branchPtr(Assembler::AboveOrEqual, argvLen, Imm32(function()->nargs()),
-                   &actualArgsSufficient);
-    masm.move32(Imm32(function()->nargs()), argvLen);
-    masm.bind(&actualArgsSufficient);
-
-    BaseValueIndex newTarget(BaselineFrameReg, argvLen, BaselineFrame::offsetOfArg(0));
-    masm.loadValue(newTarget, R0);
-
-    masm.bind(&done);
-    frame.push(R0);
-
-    return true;
-}
-
 typedef bool (*ThrowUninitializedLexicalFn)(JSContext* cx);
 static const VMFunction ThrowUninitializedLexicalInfo =
     FunctionInfo<ThrowUninitializedLexicalFn>(jit::ThrowUninitializedLexical);
 
 bool
 BaselineCompiler::emitUninitializedLexicalCheck(const ValueOperand& val)
 {
     Label done;
@@ -2791,30 +2732,29 @@ BaselineCompiler::emit_JSOP_UNINITIALIZE
     return true;
 }
 
 bool
 BaselineCompiler::emitCall()
 {
     MOZ_ASSERT(IsCallPC(pc));
 
-    bool construct = JSOp(*pc) == JSOP_NEW;
     uint32_t argc = GET_ARGC(pc);
 
     frame.syncStack(0);
     masm.move32(Imm32(argc), R0.scratchReg());
 
     // Call IC
-    ICCall_Fallback::Compiler stubCompiler(cx, /* isConstructing = */ construct,
+    ICCall_Fallback::Compiler stubCompiler(cx, /* isConstructing = */ JSOp(*pc) == JSOP_NEW,
                                            /* isSpread = */ false);
     if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
         return false;
 
     // Update FrameInfo.
-    frame.popn(2 + argc + construct);
+    frame.popn(argc + 2);
     frame.push(R0);
     return true;
 }
 
 bool
 BaselineCompiler::emitSpreadCall()
 {
     MOZ_ASSERT(IsCallPC(pc));
@@ -2824,18 +2764,17 @@ BaselineCompiler::emitSpreadCall()
 
     // Call IC
     ICCall_Fallback::Compiler stubCompiler(cx, /* isConstructing = */ JSOp(*pc) == JSOP_SPREADNEW,
                                            /* isSpread = */ true);
     if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
         return false;
 
     // Update FrameInfo.
-    bool construct = JSOp(*pc) == JSOP_SPREADNEW;
-    frame.popn(3 + construct);
+    frame.popn(3);
     frame.push(R0);
     return true;
 }
 
 bool
 BaselineCompiler::emit_JSOP_CALL()
 {
     return emitCall();
@@ -3673,29 +3612,16 @@ BaselineCompiler::emit_JSOP_RESUME()
     Register scratch1 = regs.takeAny();
     masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), scratch1);
 
     // Load the BaselineScript or call a stub if we don't have one.
     Label interpret;
     masm.loadPtr(Address(scratch1, JSScript::offsetOfBaselineScript()), scratch1);
     masm.branchPtr(Assembler::BelowOrEqual, scratch1, ImmPtr(BASELINE_DISABLED_SCRIPT), &interpret);
 
-    Register constructing = regs.takeAny();
-    ValueOperand newTarget = regs.takeAnyValue();
-    masm.loadValue(Address(genObj, GeneratorObject::offsetOfNewTargetSlot()), newTarget);
-    masm.move32(Imm32(0), constructing);
-    {
-        Label notConstructing;
-        masm.branchTestObject(Assembler::NotEqual, newTarget, &notConstructing);
-        masm.pushValue(newTarget);
-        masm.move32(Imm32(CalleeToken_FunctionConstructing), constructing);
-        masm.bind(&notConstructing);
-    }
-    regs.add(newTarget);
-
     // Push |undefined| for all formals.
     Register scratch2 = regs.takeAny();
     Label loop, loopDone;
     masm.load16ZeroExtend(Address(callee, JSFunction::offsetOfNargs()), scratch2);
     masm.bind(&loop);
     masm.branchTest32(Assembler::Zero, scratch2, scratch2, &loopDone);
     {
         masm.pushValue(UndefinedValue());
@@ -3710,24 +3636,20 @@ BaselineCompiler::emit_JSOP_RESUME()
     // Update BaselineFrame frameSize field and create the frame descriptor.
     masm.computeEffectiveAddress(Address(BaselineFrameReg, BaselineFrame::FramePointerOffset),
                                  scratch2);
     masm.subPtr(BaselineStackReg, scratch2);
     masm.store32(scratch2, Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFrameSize()));
     masm.makeFrameDescriptor(scratch2, JitFrame_BaselineJS);
 
     masm.Push(Imm32(0)); // actual argc
-
-    // Duplicate PushCalleeToken with a variable instead.
-    masm.orPtr(constructing, callee);
-    masm.Push(callee);
+    masm.PushCalleeToken(callee, false);
     masm.Push(scratch2); // frame descriptor
 
     regs.add(callee);
-    regs.add(constructing);
 
     // Load the return value.
     ValueOperand retVal = regs.takeAnyValue();
     masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), retVal);
 
     // Push a fake return address on the stack. We will resume here when the
     // generator returns.
     Label genStart, returnTarget;
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -190,18 +190,17 @@ namespace jit {
     _(JSOP_INITIALYIELD)       \
     _(JSOP_YIELD)              \
     _(JSOP_DEBUGAFTERYIELD)    \
     _(JSOP_FINALYIELDRVAL)     \
     _(JSOP_RESUME)             \
     _(JSOP_CALLEE)             \
     _(JSOP_SETRVAL)            \
     _(JSOP_RETRVAL)            \
-    _(JSOP_RETURN)             \
-    _(JSOP_NEWTARGET)
+    _(JSOP_RETURN)
 
 class BaselineCompiler : public BaselineCompilerSpecific
 {
     FixedList<Label>            labels_;
     NonAssertingLabel           return_;
     NonAssertingLabel           postBarrierSlot_;
 
     // Native code offset right before the scope chain is initialized.
--- a/js/src/jit/BaselineFrame.cpp
+++ b/js/src/jit/BaselineFrame.cpp
@@ -32,31 +32,29 @@ BaselineFrame::trace(JSTracer* trc, JitF
 {
     replaceCalleeToken(MarkCalleeToken(trc, calleeToken()));
 
     TraceRoot(trc, &thisValue(), "baseline-this");
 
     // Mark actual and formal args.
     if (isNonEvalFunctionFrame()) {
         unsigned numArgs = js::Max(numActualArgs(), numFormalArgs());
-        TraceRootRange(trc, numArgs + isConstructing(), argv(), "baseline-args");
+        TraceRootRange(trc, numArgs, argv(), "baseline-args");
     }
 
     // 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,38 +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 {
-        MOZ_ASSERT(isFunctionFrame());
-        if (isEvalFrame())
-            return *evalNewTargetAddress();
-        if (fun()->isArrow())
-            return fun()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
-        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();
@@ -416,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/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -10243,17 +10243,16 @@ TryAttachCallStub(JSContext* cx, ICCall_
         if (stub->nativeStubCount() >= ICCall_Fallback::MAX_NATIVE_STUBS) {
             JitSpew(JitSpew_BaselineIC,
                     "  Too many Call_Native stubs. TODO: add Call_AnyNative!");
             return true;
         }
 
         if (fun->native() == intrinsic_IsSuspendedStarGenerator) {
             // This intrinsic only appears in self-hosted code.
-            MOZ_ASSERT(op != JSOP_NEW);
             MOZ_ASSERT(argc == 1);
             JitSpew(JitSpew_BaselineIC, "  Generating Call_IsSuspendedStarGenerator stub");
 
             ICCall_IsSuspendedStarGenerator::Compiler compiler(cx);
             ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
             if (!newStub)
                 return false;
 
@@ -10315,20 +10314,16 @@ TryAttachStringSplit(JSContext* cx, ICCa
 {
     if (stub->numOptimizedStubs() != 0)
         return true;
 
     RootedValue callee(cx, vp[0]);
     RootedValue thisv(cx, vp[1]);
     Value* args = vp + 2;
 
-    // String.prototype.split will not yield a constructable.
-    if (JSOp(*pc) == JSOP_NEW)
-        return true;
-
     if (!IsOptimizableCallStringSplit(callee, thisv, argc, args))
         return true;
 
     MOZ_ASSERT(callee.isObject());
     MOZ_ASSERT(callee.toObject().is<JSFunction>());
 
     RootedString thisString(cx, thisv.toString());
     RootedString argString(cx, args[0].toString());
@@ -10364,51 +10359,52 @@ TryAttachStringSplit(JSContext* cx, ICCa
 
 static bool
 DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint32_t argc,
                Value* vp, MutableHandleValue res)
 {
     // This fallback stub may trigger debug mode toggling.
     DebugModeOSRVolatileStub<ICCall_Fallback*> stub(frame, stub_);
 
+    // Ensure vp array is rooted - we may GC in here.
+    AutoArrayRooter vpRoot(cx, argc + 2, vp);
+
     RootedScript script(cx, frame->script());
     jsbytecode* pc = stub->icEntry()->pc(script);
     JSOp op = JSOp(*pc);
     FallbackICSpew(cx, stub, "Call(%s)", js_CodeName[op]);
 
     MOZ_ASSERT(argc == GET_ARGC(pc));
-    bool constructing = (op == JSOP_NEW);
-
-    // Ensure vp array is rooted - we may GC in here.
-    AutoArrayRooter vpRoot(cx, argc + 2 + constructing, vp);
 
     RootedValue callee(cx, vp[0]);
     RootedValue thisv(cx, vp[1]);
 
     Value* args = vp + 2;
 
     // Handle funapply with JSOP_ARGUMENTS
     if (op == JSOP_FUNAPPLY && argc == 2 && args[1].isMagic(JS_OPTIMIZED_ARGUMENTS)) {
         CallArgs callArgs = CallArgsFromVp(argc, vp);
         if (!GuardFunApplyArgumentsOptimization(cx, frame, callArgs))
             return false;
     }
 
+    // Compute construcing and useNewGroup flags.
+    bool constructing = (op == JSOP_NEW);
     bool createSingleton = ObjectGroup::useSingletonForNewObject(cx, script, pc);
 
     // Try attaching a call stub.
     bool handled = false;
     if (!TryAttachCallStub(cx, stub, script, pc, op, argc, vp, constructing, false,
                            createSingleton, &handled))
     {
         return false;
     }
 
     if (op == JSOP_NEW) {
-        if (!InvokeConstructor(cx, callee, argc, args, true, res))
+        if (!InvokeConstructor(cx, callee, argc, args, res))
             return false;
     } else if ((op == JSOP_EVAL || op == JSOP_STRICTEVAL) &&
                frame->scopeChain()->global().valueIsEval(callee))
     {
         if (!DirectEval(cx, CallArgsFromVp(argc, vp)))
             return false;
         res.set(vp[0]);
     } else {
@@ -10447,40 +10443,40 @@ DoCallFallback(JSContext* cx, BaselineFr
 
 static bool
 DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, Value* vp,
                      MutableHandleValue res)
 {
     // This fallback stub may trigger debug mode toggling.
     DebugModeOSRVolatileStub<ICCall_Fallback*> stub(frame, stub_);
 
+    // Ensure vp array is rooted - we may GC in here.
+    AutoArrayRooter vpRoot(cx, 3, vp);
+
     RootedScript script(cx, frame->script());
     jsbytecode* pc = stub->icEntry()->pc(script);
     JSOp op = JSOp(*pc);
-    bool constructing = (op == JSOP_SPREADNEW);
     FallbackICSpew(cx, stub, "SpreadCall(%s)", js_CodeName[op]);
 
-    // Ensure vp array is rooted - we may GC in here.
-    AutoArrayRooter vpRoot(cx, 3 + constructing, vp);
-
     RootedValue callee(cx, vp[0]);
     RootedValue thisv(cx, vp[1]);
     RootedValue arr(cx, vp[2]);
-    RootedValue newTarget(cx, constructing ? vp[3] : NullValue());
+
+    bool constructing = (op == JSOP_SPREADNEW);
 
     // Try attaching a call stub.
     bool handled = false;
     if (op != JSOP_SPREADEVAL && op != JSOP_STRICTSPREADEVAL &&
         !TryAttachCallStub(cx, stub, script, pc, op, 1, vp, constructing, true, false,
                            &handled))
     {
         return false;
     }
 
-    if (!SpreadCallOperation(cx, script, pc, thisv, callee, arr, newTarget, res))
+    if (!SpreadCallOperation(cx, script, pc, thisv, callee, arr, res))
         return false;
 
     // Check if debug mode toggling made the stub invalid.
     if (stub.invalid())
         return true;
 
     // Attach a new TypeMonitor stub for this value.
     ICTypeMonitor_Fallback* typeMonFbStub = stub->fallbackMonitorStub();
@@ -10492,138 +10488,103 @@ DoSpreadCallFallback(JSContext* cx, Base
 
     if (!handled)
         stub->noteUnoptimizableCall();
     return true;
 }
 
 void
 ICCallStubCompiler::pushCallArguments(MacroAssembler& masm, AllocatableGeneralRegisterSet regs,
-                                      Register argcReg, bool isJitCall, bool isConstructing)
+                                      Register argcReg, bool isJitCall)
 {
     MOZ_ASSERT(!regs.has(argcReg));
 
-    // Account for new.target
+    // Push the callee and |this| too.
     Register count = regs.takeAny();
-
     masm.mov(argcReg, count);
-
-    // If we are setting up for a jitcall, we have to align the stack taking
-    // into account the args and newTarget. We could also count callee and |this|,
-    // but it's a waste of stack space. Because we want to keep argcReg unchanged,
-    // just account for newTarget initially, and add the other 2 after assuring
-    // allignment.
-    if (isJitCall) {
-        if (isConstructing)
-            masm.add32(Imm32(1), count);
-    } else {
-        masm.add32(Imm32(2 + isConstructing), count);
-    }
+    masm.add32(Imm32(2), count);
 
     // argPtr initially points to the last argument.
     Register argPtr = regs.takeAny();
     masm.mov(BaselineStackReg, argPtr);
 
     // Skip 4 pointers pushed on top of the arguments: the frame descriptor,
     // return address, old frame pointer and stub reg.
     masm.addPtr(Imm32(STUB_FRAME_SIZE), argPtr);
 
     // Align the stack such that the JitFrameLayout is aligned on the
     // JitStackAlignment.
-    if (isJitCall) {
-        masm.alignJitStackBasedOnNArgs(count);
-
-        // Account for callee and |this|, skipped earlier
-        masm.add32(Imm32(2), count);
-    }
+    if (isJitCall)
+        masm.alignJitStackBasedOnNArgs(argcReg);
 
     // Push all values, starting at the last one.
     Label loop, done;
     masm.bind(&loop);
     masm.branchTest32(Assembler::Zero, count, count, &done);
     {
         masm.pushValue(Address(argPtr, 0));
         masm.addPtr(Imm32(sizeof(Value)), argPtr);
 
         masm.sub32(Imm32(1), count);
         masm.jump(&loop);
     }
     masm.bind(&done);
 }
 
 void
-ICCallStubCompiler::guardSpreadCall(MacroAssembler& masm, Register argcReg, Label* failure,
-                                    bool isConstructing)
-{
-    masm.unboxObject(Address(BaselineStackReg, isConstructing * sizeof(Value) + ICStackValueOffset), argcReg);
+ICCallStubCompiler::guardSpreadCall(MacroAssembler& masm, Register argcReg, Label* failure)
+{
+    masm.unboxObject(Address(BaselineStackReg, ICStackValueOffset), argcReg);
     masm.loadPtr(Address(argcReg, NativeObject::offsetOfElements()), argcReg);
     masm.load32(Address(argcReg, ObjectElements::offsetOfLength()), argcReg);
 
     // Limit actual argc to something reasonable (huge number of arguments can
     // blow the stack limit).
     static_assert(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH <= ARGS_LENGTH_MAX,
                   "maximum arguments length for optimized stub should be <= ARGS_LENGTH_MAX");
     masm.branch32(Assembler::Above, argcReg, Imm32(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH),
                   failure);
 }
 
 void
 ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler& masm,
                                             AllocatableGeneralRegisterSet regs,
-                                            Register argcReg, bool isJitCall,
-                                            bool isConstructing)
-{
-    // Pull the array off the stack before aligning.
+                                            Register argcReg, bool isJitCall)
+{
+    // Push arguments
     Register startReg = regs.takeAny();
-    masm.unboxObject(Address(BaselineStackReg, (isConstructing * sizeof(Value)) + STUB_FRAME_SIZE), startReg);
+    Register endReg = regs.takeAny();
+    masm.unboxObject(Address(BaselineStackReg, STUB_FRAME_SIZE), startReg);
     masm.loadPtr(Address(startReg, NativeObject::offsetOfElements()), startReg);
-    
-    // Align the stack such that the JitFrameLayout is aligned on the
-    // JitStackAlignment.
-    if (isJitCall) {
-        Register alignReg = argcReg;
-        if (isConstructing) {
-            alignReg = regs.takeAny();
-            masm.mov(argcReg, alignReg);
-            masm.addPtr(Imm32(1), alignReg);
-        }
-        masm.alignJitStackBasedOnNArgs(alignReg);
-        if (isConstructing) {
-            MOZ_ASSERT(alignReg != argcReg);
-            regs.add(alignReg);
-        }
-    }
-
-    // Push newTarget, if necessary
-    if (isConstructing)
-        masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE));
-
-    // Push arguments: set up endReg to point to &array[argc]
-    Register endReg = regs.takeAny();
     masm.mov(argcReg, endReg);
     static_assert(sizeof(Value) == 8, "Value must be 8 bytes");
     masm.lshiftPtr(Imm32(3), endReg);
     masm.addPtr(startReg, endReg);
 
+    // Align the stack such that the JitFrameLayout is aligned on the
+    // JitStackAlignment.
+    if (isJitCall)
+        masm.alignJitStackBasedOnNArgs(argcReg);
+
     // Copying pre-decrements endReg by 8 until startReg is reached
     Label copyDone;
     Label copyStart;
     masm.bind(&copyStart);
     masm.branchPtr(Assembler::Equal, endReg, startReg, &copyDone);
     masm.subPtr(Imm32(sizeof(Value)), endReg);
     masm.pushValue(Address(endReg, 0));
     masm.jump(&copyStart);
     masm.bind(&copyDone);
 
     regs.add(startReg);
     regs.add(endReg);
 
     // Push the callee and |this|.
-    masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE + (1 + isConstructing) * sizeof(Value)));
-    masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE + (2 + isConstructing) * sizeof(Value)));
+    masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE + 1 * sizeof(Value)));
+    masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE + 2 * sizeof(Value)));
 }
 
 // (see Bug 1149377 comment 31) MSVC 2013 PGO miss-compiles branchTestObjClass
 // calls from this function.
 #if defined(_MSC_VER) && _MSC_VER == 1800
 # pragma optimize("g", off)
 #endif
 Register
@@ -10818,30 +10779,19 @@ ICCall_Fallback::Compiler::generateStubC
     // |this| and callee are pushed last.
 
     AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
 
     if (MOZ_UNLIKELY(isSpread_)) {
         // Use BaselineFrameReg instead of BaselineStackReg, because
         // BaselineFrameReg and BaselineStackReg hold the same value just after
         // calling enterStubFrame.
-        
-        // newTarget
-        if (isConstructing_)
-            masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE));
-        
-        // array
-        uint32_t valueOffset = isConstructing_;
-        masm.pushValue(Address(BaselineFrameReg, valueOffset++ * sizeof(Value) + STUB_FRAME_SIZE));
-        
-        // this
-        masm.pushValue(Address(BaselineFrameReg, valueOffset++ * sizeof(Value) + STUB_FRAME_SIZE));
-        
-        // callee
-        masm.pushValue(Address(BaselineFrameReg, valueOffset++ * sizeof(Value) + STUB_FRAME_SIZE));
+        masm.pushValue(Address(BaselineFrameReg, 0 * sizeof(Value) + STUB_FRAME_SIZE)); // array
+        masm.pushValue(Address(BaselineFrameReg, 1 * sizeof(Value) + STUB_FRAME_SIZE)); // this
+        masm.pushValue(Address(BaselineFrameReg, 2 * sizeof(Value) + STUB_FRAME_SIZE)); // callee
 
         masm.push(BaselineStackReg);
         masm.push(BaselineStubReg);
 
         masm.loadPtr(Address(BaselineFrameReg, 0), R0.scratchReg());
         masm.pushBaselineFramePtr(R0.scratchReg(), R0.scratchReg());
 
         if (!callVM(DoSpreadCallFallbackInfo, masm))
@@ -10852,17 +10802,17 @@ ICCall_Fallback::Compiler::generateStubC
 
         // SPREADCALL is not yet supported in Ion, so do not generate asmcode for
         // bailout.
         return true;
     }
 
     regs.take(R0.scratchReg()); // argc.
 
-    pushCallArguments(masm, regs, R0.scratchReg(), /* isJitCall = */ false, isConstructing_);
+    pushCallArguments(masm, regs, R0.scratchReg(), /* isJitCall = */ false);
 
     masm.push(BaselineStackReg);
     masm.push(R0.scratchReg());
     masm.push(BaselineStubReg);
 
     // Load previous frame pointer, push BaselineFrame*.
     masm.loadPtr(Address(BaselineFrameReg, 0), R0.scratchReg());
     masm.pushBaselineFramePtr(R0.scratchReg(), R0.scratchReg());
@@ -10880,30 +10830,34 @@ ICCall_Fallback::Compiler::generateStubC
 
     // Load passed-in ThisV into R1 just in case it's needed.  Need to do this before
     // we leave the stub frame since that info will be lost.
     // Current stack:  [...., ThisV, ActualArgc, CalleeToken, Descriptor ]
     masm.loadValue(Address(BaselineStackReg, 3 * sizeof(size_t)), R1);
 
     leaveStubFrame(masm, true);
 
+    // R1 and R0 are taken.
+    regs = availableGeneralRegs(2);
+    Register scratch = regs.takeAny();
+
     // If this is a |constructing| call, if the callee returns a non-object, we replace it with
     // the |this| object passed in.
-    if (isConstructing_) {
-        MOZ_ASSERT(JSReturnOperand == R0);
-        Label skipThisReplace;
-
-        masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
-        masm.moveValue(R1, R0);
+    MOZ_ASSERT(JSReturnOperand == R0);
+    Label skipThisReplace;
+    masm.load16ZeroExtend(Address(BaselineStubReg, ICStub::offsetOfExtra()), scratch);
+    masm.branchTest32(Assembler::Zero, scratch, Imm32(ICCall_Fallback::CONSTRUCTING_FLAG),
+                      &skipThisReplace);
+    masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
+    masm.moveValue(R1, R0);
 #ifdef DEBUG
-        masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
-        masm.assumeUnreachable("Failed to return object in constructing call.");
+    masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
+    masm.assumeUnreachable("Failed to return object in constructing call.");
 #endif
-        masm.bind(&skipThisReplace);
-    }
+    masm.bind(&skipThisReplace);
 
     // At this point, BaselineStubReg points to the ICCall_Fallback stub, which is NOT
     // a MonitoredStub, but rather a MonitoredFallbackStub.  To use EmitEnterTypeMonitorIC,
     // first load the ICTypeMonitor_Fallback stub into BaselineStubReg.  Then, use
     // EmitEnterTypeMonitorIC with a custom struct offset.
     masm.loadPtr(Address(BaselineStubReg, ICMonitoredFallbackStub::offsetOfFallbackMonitorStub()),
                  BaselineStubReg);
     EmitEnterTypeMonitorIC(masm, ICTypeMonitor_Fallback::offsetOfFirstMonitorStub());
@@ -10914,18 +10868,17 @@ ICCall_Fallback::Compiler::generateStubC
 bool
 ICCall_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code)
 {
     if (MOZ_UNLIKELY(isSpread_))
         return true;
 
     CodeOffsetLabel offset(returnOffset_);
     offset.fixup(&masm);
-    cx->compartment()->jitCompartment()->initBaselineCallReturnAddr(code->raw() + offset.offset(),
-                                                                    isConstructing_);
+    cx->compartment()->jitCompartment()->initBaselineCallReturnAddr(code->raw() + offset.offset());
     return true;
 }
 
 typedef bool (*CreateThisFn)(JSContext* cx, HandleObject callee, MutableHandleValue rval);
 static const VMFunction CreateThisInfoBaseline = FunctionInfo<CreateThisFn>(CreateThis);
 
 bool
 ICCallScriptedCompiler::generateStubCode(MacroAssembler& masm)
@@ -10937,27 +10890,24 @@ ICCallScriptedCompiler::generateStubCode
     Register argcReg = R0.scratchReg();
     MOZ_ASSERT(argcReg != ArgumentsRectifierReg);
 
     regs.take(argcReg);
     regs.take(ArgumentsRectifierReg);
     regs.takeUnchecked(BaselineTailCallReg);
 
     if (isSpread_)
-        guardSpreadCall(masm, argcReg, &failure, isConstructing_);
-
-    // Load the callee in R1, accounting for newTarget, if necessary
-    // Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, ..., ArgNVal, [newTarget] +ICStackValueOffset+ ]
+        guardSpreadCall(masm, argcReg, &failure);
+
+    // Load the callee in R1.
+    // Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, ..., ArgNVal, +ICStackValueOffset+ ]
     if (isSpread_) {
-        unsigned skipToCallee = (2 + isConstructing_) * sizeof(Value);
-        masm.loadValue(Address(BaselineStackReg, skipToCallee + ICStackValueOffset), R1);
+        masm.loadValue(Address(BaselineStackReg, 2 * sizeof(Value) + ICStackValueOffset), R1);
     } else {
-        // Account for newTarget, if necessary
-        unsigned nonArgsSkip = (1 + isConstructing_) * sizeof(Value);
-        BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + nonArgsSkip);
+        BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + sizeof(Value));
         masm.loadValue(calleeSlot, R1);
     }
     regs.take(R1);
 
     // Ensure callee is an object.
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     // Ensure callee is a function.
@@ -11007,23 +10957,23 @@ ICCallScriptedCompiler::generateStubCode
 
     Label failureLeaveStubFrame;
 
     if (isConstructing_) {
         // Save argc before call.
         masm.push(argcReg);
 
         // Stack now looks like:
-        //      [..., Callee, ThisV, Arg0V, ..., ArgNV, NewTarget, StubFrameHeader, ArgC ]
+        //      [..., Callee, ThisV, Arg0V, ..., ArgNV, StubFrameHeader, ArgC ]
         if (isSpread_) {
             masm.loadValue(Address(BaselineStackReg,
-                                   3 * sizeof(Value) + STUB_FRAME_SIZE + sizeof(size_t)), R1);
+                                   2 * sizeof(Value) + STUB_FRAME_SIZE + sizeof(size_t)), R1);
         } else {
             BaseValueIndex calleeSlot2(BaselineStackReg, argcReg,
-                                       2 * sizeof(Value) + STUB_FRAME_SIZE + sizeof(size_t));
+                                       sizeof(Value) + STUB_FRAME_SIZE + sizeof(size_t));
             masm.loadValue(calleeSlot2, R1);
         }
         masm.push(masm.extractObject(R1, ExtractTemp0));
         if (!callVM(CreateThisInfoBaseline, masm))
             return false;
 
         // Return of CreateThis must be an object.
 #ifdef DEBUG
@@ -11041,40 +10991,37 @@ ICCallScriptedCompiler::generateStubCode
         argcReg = regs.takeAny();
 
         // Restore saved argc so we can use it to calculate the address to save
         // the resulting this object to.
         masm.pop(argcReg);
 
         // Save "this" value back into pushed arguments on stack.  R0 can be clobbered after that.
         // Stack now looks like:
-        //      [..., Callee, ThisV, Arg0V, ..., ArgNV, [NewTarget], StubFrameHeader ]
+        //      [..., Callee, ThisV, Arg0V, ..., ArgNV, StubFrameHeader ]
         if (isSpread_) {
-            masm.storeValue(R0, Address(BaselineStackReg, (1 + isConstructing_) * sizeof(Value) + STUB_FRAME_SIZE));
+            masm.storeValue(R0, Address(BaselineStackReg, sizeof(Value) + STUB_FRAME_SIZE));
         } else {
-            BaseValueIndex thisSlot(BaselineStackReg, argcReg, STUB_FRAME_SIZE + isConstructing_ * sizeof(Value));
+            BaseValueIndex thisSlot(BaselineStackReg, argcReg, STUB_FRAME_SIZE);
             masm.storeValue(R0, thisSlot);
         }
 
         // Restore the stub register from the baseline stub frame.
         masm.loadPtr(Address(BaselineStackReg, STUB_FRAME_SAVED_STUB_OFFSET), BaselineStubReg);
 
         // Reload callee script. Note that a GC triggered by CreateThis may
         // have destroyed the callee BaselineScript and IonScript. CreateThis is
         // safely repeatable though, so in this case we just leave the stub frame
         // and jump to the next stub.
 
         // Just need to load the script now.
         if (isSpread_) {
-            unsigned skipForCallee = (2 + isConstructing_) * sizeof(Value);
-            masm.loadValue(Address(BaselineStackReg, skipForCallee + STUB_FRAME_SIZE), R0);
+            masm.loadValue(Address(BaselineStackReg, 2 * sizeof(Value) + STUB_FRAME_SIZE), R0);
         } else {
-            // Account for newTarget, if necessary
-            unsigned nonArgsSkip = (1 + isConstructing_) * sizeof(Value);
-            BaseValueIndex calleeSlot3(BaselineStackReg, argcReg, nonArgsSkip + STUB_FRAME_SIZE);
+            BaseValueIndex calleeSlot3(BaselineStackReg, argcReg, sizeof(Value) + STUB_FRAME_SIZE);
             masm.loadValue(calleeSlot3, R0);
         }
         callee = masm.extractObject(R0, ExtractTemp0);
         regs.add(R0);
         regs.takeUnchecked(callee);
         masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
 
         code = regs.takeAny();
@@ -11090,19 +11037,19 @@ ICCallScriptedCompiler::generateStubCode
             regs.addUnchecked(BaselineTailCallReg);
     }
     Register scratch = regs.takeAny();
 
     // Values are on the stack left-to-right. Calling convention wants them
     // right-to-left so duplicate them on the stack in reverse order.
     // |this| and callee are pushed last.
     if (isSpread_)
-        pushSpreadCallArguments(masm, regs, argcReg, /* isJitCall = */ true, isConstructing_);
+        pushSpreadCallArguments(masm, regs, argcReg, /* isJitCall = */ true);
     else
-        pushCallArguments(masm, regs, argcReg, /* isJitCall = */ true, isConstructing_);
+        pushCallArguments(masm, regs, argcReg, /* isJitCall = */ true);
 
     // The callee is on top of the stack. Pop and unbox it.
     ValueOperand val = regs.takeAnyValue();
     masm.popValue(val);
     callee = masm.extractObject(val, ExtractTemp0);
 
     EmitCreateStubFrameDescriptor(masm, scratch);
 
@@ -11164,20 +11111,18 @@ ICCallScriptedCompiler::generateStubCode
         } else {
             Address argcAddr(BaselineStackReg, 2 * sizeof(size_t));
             masm.loadPtr(argcAddr, argcReg);
         }
 
         // Current stack: [ ThisVal, ARGVALS..., ...STUB FRAME..., <-- BaselineFrameReg
         //                  Padding?, ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
         //
-        // &ThisVal = BaselineFrameReg + argc * sizeof(Value) + STUB_FRAME_SIZE + sizeof(Value)
-        // This last sizeof(Value) accounts for the newTarget on the end of the arguments vector
-        // which is not reflected in actualArgc
-        BaseValueIndex thisSlotAddr(BaselineFrameReg, argcReg, STUB_FRAME_SIZE + sizeof(Value));
+        // &ThisVal = BaselineFrameReg + argc * sizeof(Value) + STUB_FRAME_SIZE
+        BaseValueIndex thisSlotAddr(BaselineFrameReg, argcReg, STUB_FRAME_SIZE);
         masm.loadValue(thisSlotAddr, JSReturnOperand);
 #ifdef DEBUG
         masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
         masm.assumeUnreachable("Return of constructing call should be an object.");
 #endif
         masm.bind(&skipThisReplace);
     }
 
@@ -11339,24 +11284,23 @@ ICCall_Native::Compiler::generateStubCod
     Label failure;
     AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
 
     Register argcReg = R0.scratchReg();
     regs.take(argcReg);
     regs.takeUnchecked(BaselineTailCallReg);
 
     if (isSpread_)
-        guardSpreadCall(masm, argcReg, &failure, isConstructing_);
+        guardSpreadCall(masm, argcReg, &failure);
 
     // Load the callee in R1.
     if (isSpread_) {
         masm.loadValue(Address(BaselineStackReg, ICStackValueOffset + 2 * sizeof(Value)), R1);
     } else {
-        unsigned nonArgsSlots = (1 + isConstructing_) * sizeof(Value);
-        BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + nonArgsSlots);
+        BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + sizeof(Value));
         masm.loadValue(calleeSlot, R1);
     }
     regs.take(R1);
 
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     // Ensure callee matches this stub's callee.
     Register callee = masm.extractObject(R1, ExtractTemp0);
@@ -11369,19 +11313,19 @@ ICCall_Native::Compiler::generateStubCod
     // Push a stub frame so that we can perform a non-tail call.
     // Note that this leaves the return address in TailCallReg.
     enterStubFrame(masm, regs.getAny());
 
     // Values are on the stack left-to-right. Calling convention wants them
     // right-to-left so duplicate them on the stack in reverse order.
     // |this| and callee are pushed last.
     if (isSpread_)
-        pushSpreadCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
+        pushSpreadCallArguments(masm, regs, argcReg, /* isJitCall = */ false);
     else
-        pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
+        pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false);
 
     if (isConstructing_) {
         // Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
         // Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
         masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(BaselineStackReg, sizeof(Value)));
     }
 
     masm.checkStackAlignment();
@@ -11444,18 +11388,17 @@ ICCall_ClassHook::Compiler::generateStub
     Label failure;
     AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
 
     Register argcReg = R0.scratchReg();
     regs.take(argcReg);
     regs.takeUnchecked(BaselineTailCallReg);
 
     // Load the callee in R1.
-    unsigned nonArgSlots = (1 + isConstructing_) * sizeof(Value);
-    BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + nonArgSlots);
+    BaseValueIndex calleeSlot(BaselineStackReg, argcReg, ICStackValueOffset + sizeof(Value));
     masm.loadValue(calleeSlot, R1);
     regs.take(R1);
 
     masm.branchTestObject(Assembler::NotEqual, R1, &failure);
 
     // Ensure the callee's class matches the one in this stub.
     Register callee = masm.extractObject(R1, ExtractTemp0);
     Register scratch = regs.takeAny();
@@ -11467,17 +11410,17 @@ ICCall_ClassHook::Compiler::generateStub
     regs.add(R1);
     regs.takeUnchecked(callee);
 
     // Push a stub frame so that we can perform a non-tail call.
     // Note that this leaves the return address in TailCallReg.
     enterStubFrame(masm, regs.getAny());
 
     regs.add(scratch);
-    pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
+    pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false);
     regs.take(scratch);
 
     if (isConstructing_) {
         // Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
         // Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
         masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(BaselineStackReg, sizeof(Value)));
     }
 
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -5517,45 +5517,53 @@ class ICCallStubCompiler : public ICStub
     { }
 
     enum FunApplyThing {
         FunApply_MagicArgs,
         FunApply_Array
     };
 
     void pushCallArguments(MacroAssembler& masm, AllocatableGeneralRegisterSet regs,
-                           Register argcReg, bool isJitCall, bool isConstructing = false);
+                           Register argcReg, bool isJitCall);
     void pushSpreadCallArguments(MacroAssembler& masm, AllocatableGeneralRegisterSet regs,
-                                 Register argcReg, bool isJitCall, bool isConstructing);
-    void guardSpreadCall(MacroAssembler& masm, Register argcReg, Label* failure,
-                         bool isConstructing);
+                                 Register argcReg, bool isJitCall);
+    void guardSpreadCall(MacroAssembler& masm, Register argcReg, Label* failure);
     Register guardFunApply(MacroAssembler& masm, AllocatableGeneralRegisterSet regs,
                            Register argcReg, bool checkNative, FunApplyThing applyThing,
                            Label* failure);
     void pushCallerArguments(MacroAssembler& masm, AllocatableGeneralRegisterSet regs);
     void pushArrayArguments(MacroAssembler& masm, Address arrayVal,
                             AllocatableGeneralRegisterSet regs);
 };
 
 class ICCall_Fallback : public ICMonitoredFallbackStub
 {
     friend class ICStubSpace;
   public:
-    static const unsigned UNOPTIMIZABLE_CALL_FLAG = 0x1;
+    static const unsigned CONSTRUCTING_FLAG = 0x1;
+    static const unsigned UNOPTIMIZABLE_CALL_FLAG = 0x2;
 
     static const uint32_t MAX_OPTIMIZED_STUBS = 16;
     static const uint32_t MAX_SCRIPTED_STUBS = 7;
     static const uint32_t MAX_NATIVE_STUBS = 7;
   private:
 
-    explicit ICCall_Fallback(JitCode* stubCode)
+    ICCall_Fallback(JitCode* stubCode, bool isConstructing)
       : ICMonitoredFallbackStub(ICStub::Call_Fallback, stubCode)
-    { }
-
-  public:
+    {
+        extra_ = 0;
+        if (isConstructing)
+            extra_ |= CONSTRUCTING_FLAG;
+    }
+
+  public:
+    bool isConstructing() const {
+        return extra_ & CONSTRUCTING_FLAG;
+    }
+
     void noteUnoptimizableCall() {
         extra_ |= UNOPTIMIZABLE_CALL_FLAG;
     }
     bool hadUnoptimizableCall() const {
         return extra_ & UNOPTIMIZABLE_CALL_FLAG;
     }
 
     unsigned scriptedStubCount() const {
@@ -5570,40 +5578,36 @@ class ICCall_Fallback : public ICMonitor
     }
     bool nativeStubsAreGeneralized() const {
         // Return hasStub(Call_AnyNative) after Call_AnyNative stub is added.
         return false;
     }
 
     // Compiler for this stub kind.
     class Compiler : public ICCallStubCompiler {
-      public:
-        static const int32_t CALL_KEY = static_cast<int32_t>(ICStub::Call_Fallback);
-        static const int32_t CONSTRUCT_KEY = static_cast<int32_t>(ICStub::Call_Fallback) | (1 << 17);
       protected:
         bool isConstructing_;
         bool isSpread_;
         uint32_t returnOffset_;
         bool generateStubCode(MacroAssembler& masm);
         bool postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code);
 
         virtual int32_t getKey() const {
-            return static_cast<int32_t>(kind) | (static_cast<int32_t>(isSpread_) << 16) |
-                   (static_cast<int32_t>(isConstructing_) << 17);
+            return static_cast<int32_t>(kind) | (static_cast<int32_t>(isSpread_) << 16);
         }
 
       public:
         Compiler(JSContext* cx, bool isConstructing, bool isSpread)
           : ICCallStubCompiler(cx, ICStub::Call_Fallback),
             isConstructing_(isConstructing),
             isSpread_(isSpread)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            ICCall_Fallback* stub = newStub<ICCall_Fallback>(space, getStubCode());
+            ICCall_Fallback* stub = newStub<ICCall_Fallback>(space, getStubCode(), isConstructing_);
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 class ICCall_Scripted : public ICMonitoredStub
--- 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
@@ -1715,31 +1715,30 @@ CodeGenerator::visitLambda(LLambda* lir)
         static_assert(FunctionExtended::NUM_EXTENDED_SLOTS == 2, "All slots must be initialized");
         masm.storeValue(UndefinedValue(), Address(output, FunctionExtended::offsetOfExtendedSlot(0)));
         masm.storeValue(UndefinedValue(), Address(output, FunctionExtended::offsetOfExtendedSlot(1)));
     }
 
     masm.bind(ool->rejoin());
 }
 
-typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, HandleValue, HandleValue);
+typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, HandleValue);
 static const VMFunction LambdaArrowInfo = FunctionInfo<LambdaArrowFn>(js::LambdaArrow);
 
 void
 CodeGenerator::visitLambdaArrow(LLambdaArrow* lir)
 {
     Register scopeChain = ToRegister(lir->scopeChain());
     ValueOperand thisv = ToValue(lir, LLambdaArrow::ThisValue);
-    ValueOperand newTargetv = ToValue(lir, LLambdaArrow::NewTargetValue);
     Register output = ToRegister(lir->output());
     Register tempReg = ToRegister(lir->temp());
     const LambdaFunctionInfo& info = lir->mir()->info();
 
     OutOfLineCode* ool = oolCallVM(LambdaArrowInfo, lir,
-                                   (ArgList(), ImmGCPtr(info.fun), scopeChain, thisv, newTargetv),
+                                   (ArgList(), ImmGCPtr(info.fun), scopeChain, thisv),
                                    StoreRegisterTo(output));
 
     MOZ_ASSERT(!info.useSingletonForClone);
 
     if (info.singletonType) {
         // If the function has a singleton type, this instruction will only be
         // executed once so we don't bother inlining it.
         masm.jump(ool->entry());
@@ -1750,20 +1749,18 @@ CodeGenerator::visitLambdaArrow(LLambdaA
     masm.createGCObject(output, tempReg, info.fun, gc::DefaultHeap, ool->entry());
 
     emitLambdaInit(output, scopeChain, info);
 
     // Initialize extended slots. Lexical |this| is stored in the first one.
     MOZ_ASSERT(info.flags & JSFunction::EXTENDED);
     static_assert(FunctionExtended::NUM_EXTENDED_SLOTS == 2, "All slots must be initialized");
     static_assert(FunctionExtended::ARROW_THIS_SLOT == 0, "|this| must be stored in first slot");
-    static_assert(FunctionExtended::ARROW_NEWTARGET_SLOT == 1,
-                  "|new.target| must be stored in second slot");
     masm.storeValue(thisv, Address(output, FunctionExtended::offsetOfExtendedSlot(0)));
-    masm.storeValue(newTargetv, Address(output, FunctionExtended::offsetOfExtendedSlot(1)));
+    masm.storeValue(UndefinedValue(), Address(output, FunctionExtended::offsetOfExtendedSlot(1)));
 
     masm.bind(ool->rejoin());
 }
 
 void
 CodeGenerator::emitLambdaInit(Register output, Register scopeChain,
                               const LambdaFunctionInfo& info)
 {
@@ -2930,30 +2927,29 @@ static const VMFunction GetIntrinsicValu
 
 void
 CodeGenerator::visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir)
 {
     pushArg(ImmGCPtr(lir->mir()->name()));
     callVM(GetIntrinsicValueInfo, lir);
 }
 
-typedef bool (*InvokeFunctionFn)(JSContext*, HandleObject, bool, uint32_t, Value*, Value*);
+typedef bool (*InvokeFunctionFn)(JSContext*, HandleObject, uint32_t, Value*, Value*);
 static const VMFunction InvokeFunctionInfo = FunctionInfo<InvokeFunctionFn>(InvokeFunction);
 
 void
 CodeGenerator::emitCallInvokeFunction(LInstruction* call, Register calleereg,
-                                      bool constructing, uint32_t argc, uint32_t unusedStack)
+                                      uint32_t argc, uint32_t unusedStack)
 {
     // Nestle %esp up to the argument vector.
     // Each path must account for framePushed_ separately, for callVM to be valid.
     masm.freeStack(unusedStack);
 
     pushArg(masm.getStackPointer()); // argv.
     pushArg(Imm32(argc));            // argc.
-    pushArg(Imm32(constructing));    // constructing.
     pushArg(calleereg);              // JSFunction*.
 
     callVM(InvokeFunctionInfo, call);
 
     // Un-nestle %esp from the argument vector. No prefix was pushed.
     masm.reserveStack(unusedStack);
 }
 
@@ -2998,18 +2994,17 @@ CodeGenerator::visitCallGeneric(LCallGen
     uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), JitFrame_IonJS);
     masm.Push(Imm32(call->numActualArgs()));
     masm.PushCalleeToken(calleereg, call->mir()->isConstructing());
     masm.Push(Imm32(descriptor));
 
     // Check whether the provided arguments satisfy target argc.
     // We cannot have lowered to LCallGeneric with a known target. Assert that we didn't
     // add any undefineds in IonBuilder. NB: MCall::numStackArgs includes |this|.
-    DebugOnly<unsigned> numNonArgsOnStack = 1 + call->isConstructing();
-    MOZ_ASSERT(call->numActualArgs() == call->mir()->numStackArgs() - numNonArgsOnStack);
+    MOZ_ASSERT(call->numActualArgs() == call->mir()->numStackArgs() - 1);
     masm.load16ZeroExtend(Address(calleereg, JSFunction::offsetOfNargs()), nargsreg);
     masm.branch32(Assembler::Above, nargsreg, Imm32(call->numActualArgs()), &thunk);
     masm.jump(&makeCall);
 
     // Argument fixed needed. Load the ArgumentsRectifier.
     masm.bind(&thunk);
     {
         MOZ_ASSERT(ArgumentsRectifierReg != objreg);
@@ -3026,65 +3021,43 @@ CodeGenerator::visitCallGeneric(LCallGen
     // Increment to remove IonFramePrefix; decrement to fill FrameSizeClass.
     // The return address has already been removed from the Ion frame.
     int prefixGarbage = sizeof(JitFrameLayout) - sizeof(void*);
     masm.adjustStack(prefixGarbage - unusedStack);
     masm.jump(&end);
 
     // Handle uncompiled or native functions.
     masm.bind(&invoke);
-    emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->numActualArgs(),
-                           unusedStack);
+    emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack);
 
     masm.bind(&end);
 
     // If the return value of the constructing function is Primitive,
     // replace the return value with the Object from CreateThis.
     if (call->mir()->isConstructing()) {
         Label notPrimitive;
         masm.branchTestPrimitive(Assembler::NotEqual, JSReturnOperand, &notPrimitive);
         masm.loadValue(Address(masm.getStackPointer(), unusedStack), JSReturnOperand);
         masm.bind(&notPrimitive);
     }
 }
 
-typedef bool (*InvokeFunctionShuffleFn)(JSContext*, HandleObject, uint32_t, uint32_t, Value*,
-                                        Value*);
-static const VMFunction InvokeFunctionShuffleInfo =
-    FunctionInfo<InvokeFunctionShuffleFn>(InvokeFunctionShuffleNewTarget);
-void
-CodeGenerator::emitCallInvokeFunctionShuffleNewTarget(LCallKnown* call, Register calleeReg,
-                                                      uint32_t numFormals, uint32_t unusedStack)
-{
-    masm.freeStack(unusedStack);
-
-    pushArg(masm.getStackPointer());
-    pushArg(Imm32(numFormals));
-    pushArg(Imm32(call->numActualArgs()));
-    pushArg(calleeReg);
-
-    callVM(InvokeFunctionShuffleInfo, call);
-
-    masm.reserveStack(unusedStack);
-}
-
 void
 CodeGenerator::visitCallKnown(LCallKnown* call)
 {
     Register calleereg = ToRegister(call->getFunction());
     Register objreg    = ToRegister(call->getTempObject());
     uint32_t unusedStack = StackOffsetOfPassedArg(call->argslot());
     DebugOnly<JSFunction*> target = call->getSingleTarget();
     Label end, uncompiled;
 
     // Native single targets are handled by LCallNative.
     MOZ_ASSERT(!target->isNative());
     // Missing arguments must have been explicitly appended by the IonBuilder.
-    DebugOnly<unsigned> numNonArgsOnStack = 1 + call->isConstructing();
-    MOZ_ASSERT(target->nargs() <= call->mir()->numStackArgs() - numNonArgsOnStack);
+    MOZ_ASSERT(target->nargs() <= call->mir()->numStackArgs() - 1);
 
     MOZ_ASSERT_IF(call->mir()->isConstructing(), target->isConstructor());
 
     masm.checkStackAlignment();
 
     // The calleereg is known to be a non-native function, but might point to
     // a LazyScript instead of a JSScript.
     masm.branchIfFunctionHasNoScript(calleereg, &uncompiled);
@@ -3114,20 +3087,17 @@ CodeGenerator::visitCallKnown(LCallKnown
     // Increment to remove IonFramePrefix; decrement to fill FrameSizeClass.
     // The return address has already been removed from the Ion frame.
     int prefixGarbage = sizeof(JitFrameLayout) - sizeof(void*);
     masm.adjustStack(prefixGarbage - unusedStack);
     masm.jump(&end);
 
     // Handle uncompiled functions.
     masm.bind(&uncompiled);
-    if (call->isConstructing() && target->nargs() > call->numActualArgs())
-        emitCallInvokeFunctionShuffleNewTarget(call, calleereg, target->nargs(), unusedStack);
-    else
-        emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->numActualArgs(), unusedStack);
+    emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack);
 
     masm.bind(&end);
 
     // If the return value of the constructing function is Primitive,
     // replace the return value with the Object from CreateThis.
     if (call->mir()->isConstructing()) {
         Label notPrimitive;
         masm.branchTestPrimitive(Assembler::NotEqual, JSReturnOperand, &notPrimitive);
@@ -3143,17 +3113,16 @@ CodeGenerator::emitCallInvokeFunction(LA
     MOZ_ASSERT(objreg != extraStackSize);
 
     // Push the space used by the arguments.
     masm.moveStackPtrTo(objreg);
     masm.Push(extraStackSize);
 
     pushArg(objreg);                           // argv.
     pushArg(ToRegister(apply->getArgc()));     // argc.
-    pushArg(Imm32(false));                     // isConstrucing.
     pushArg(ToRegister(apply->getFunction())); // JSFunction*.
 
     // This specialization og callVM restore the extraStackSize after the call.
     callVM(InvokeFunctionInfo, apply, &extraStackSize);
 
     masm.Pop(extraStackSize);
 }
 
@@ -3483,36 +3452,53 @@ 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)
+CodeGenerator::visitCallDirectEvalS(LCallDirectEvalS* 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(ToValue(lir, LCallDirectEvalS::ThisValue));
     pushArg(ImmGCPtr(gen->info().script()));
     pushArg(scopeChain);
 
     callVM(DirectEvalStringInfo, lir);
 }
 
+typedef bool (*DirectEvalVFn)(JSContext*, HandleObject, HandleScript, HandleValue, HandleValue,
+                              jsbytecode*, MutableHandleValue);
+static const VMFunction DirectEvalValueInfo = FunctionInfo<DirectEvalVFn>(DirectEvalValueFromIon);
+
+void
+CodeGenerator::visitCallDirectEvalV(LCallDirectEvalV* lir)
+{
+    Register scopeChain = ToRegister(lir->getScopeChain());
+
+    pushArg(ImmPtr(lir->mir()->pc()));
+    pushArg(ToValue(lir, LCallDirectEvalV::Argument));
+    pushArg(ToValue(lir, LCallDirectEvalV::ThisValue));
+    pushArg(ImmGCPtr(gen->info().script()));
+    pushArg(scopeChain);
+
+    callVM(DirectEvalValueInfo, lir);
+}
+
 void
 CodeGenerator::generateArgumentsChecks(bool bailout)
 {
     // Registers safe for use before generatePrologue().
     static const uint32_t EntryTempMask = Registers::TempMask & ~(1 << OsrFrameReg.code());
 
     // This function can be used the normal way to check the argument types,
     // before entering the function and bailout when arguments don't match.
@@ -4964,24 +4950,16 @@ void
 CodeGenerator::visitLoadArrowThis(LLoadArrowThis* lir)
 {
     Register callee = ToRegister(lir->callee());
     ValueOperand output = ToOutValue(lir);
     masm.loadValue(Address(callee, FunctionExtended::offsetOfArrowThisSlot()), output);
 }
 
 void
-CodeGenerator::visitArrowNewTarget(LArrowNewTarget* lir)
-{
-    Register callee = ToRegister(lir->callee());
-    ValueOperand output = ToOutValue(lir);
-    masm.loadValue(Address(callee, FunctionExtended::offsetOfArrowNewTargetSlot()), output);
-}
-
-void
 CodeGenerator::visitArrayLength(LArrayLength* lir)
 {
     Address length(ToRegister(lir->elements()), ObjectElements::offsetOfLength());
     masm.load32(length, ToRegister(lir->output()));
 }
 
 void
 CodeGenerator::visitSetArrayLength(LSetArrayLength* lir)
@@ -10063,45 +10041,10 @@ CodeGenerator::visitDebugger(LDebugger* 
     masm.passABIArg(cx);
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GlobalHasLiveOnDebuggerStatement));
 
     Label bail;
     masm.branchIfTrueBool(ReturnReg, &bail);
     bailoutFrom(&bail, ins->snapshot());
 }
 
-void
-CodeGenerator::visitNewTarget(LNewTarget *ins)
-{
-    ValueOperand output = GetValueOutput(ins);
-
-    // if (!isConstructing()) output = undefined
-    Label constructing, done;
-    Address calleeToken(masm.getStackPointer(), frameSize() + JitFrameLayout::offsetOfCalleeToken());
-    masm.branchTestPtr(Assembler::NonZero, calleeToken,
-                       Imm32(CalleeToken_FunctionConstructing), &constructing);
-    masm.moveValue(UndefinedValue(), output);
-    masm.jump(&done);
-
-    masm.bind(&constructing);
-
-    // else output = argv[Max(numActualArgs, numFormalArgs)]
-    Register argvLen = output.scratchReg();
-
-    Address actualArgsPtr(masm.getStackPointer(), frameSize() + JitFrameLayout::offsetOfNumActualArgs());
-    masm.loadPtr(actualArgsPtr, argvLen);
-
-    Label actualArgsSufficient;
-
-    size_t numFormalArgs = ins->mirRaw()->block()->info().funMaybeLazy()->nargs();
-    masm.branchPtr(Assembler::AboveOrEqual, argvLen, Imm32(numFormalArgs),
-                   &actualArgsSufficient);
-    masm.move32(Imm32(numFormalArgs), argvLen);
-    masm.bind(&actualArgsSufficient);
-
-    BaseValueIndex newTarget(masm.getStackPointer(), argvLen, frameSize() + JitFrameLayout::offsetOfActualArgs());
-    masm.loadValue(newTarget, output);
-
-    masm.bind(&done);
-}
-
 } // namespace jit
 } // namespace js
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -125,35 +125,31 @@ class CodeGenerator : public CodeGenerat
     void visitTypeBarrierV(LTypeBarrierV* lir);
     void visitTypeBarrierO(LTypeBarrierO* lir);
     void visitMonitorTypes(LMonitorTypes* lir);
     void visitPostWriteBarrierO(LPostWriteBarrierO* lir);
     void visitPostWriteBarrierV(LPostWriteBarrierV* lir);
     void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool);
     void visitCallNative(LCallNative* call);
     void emitCallInvokeFunction(LInstruction* call, Register callereg,
-                                bool isConstructing, uint32_t argc,
-                                uint32_t unusedStack);
+                                uint32_t argc, uint32_t unusedStack);
     void visitCallGeneric(LCallGeneric* call);
-    void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call,
-                                                Register calleeReg,
-                                                uint32_t numFormals,
-                                                uint32_t unusedStack);
     void visitCallKnown(LCallKnown* call);
     void emitCallInvokeFunction(LApplyArgsGeneric* apply, Register extraStackSize);
     void emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSpace);
     void emitPopArguments(LApplyArgsGeneric* apply, Register extraStackSize);
     void visitApplyArgsGeneric(LApplyArgsGeneric* apply);
     void visitBail(LBail* lir);
     void visitUnreachable(LUnreachable* unreachable);
     void visitEncodeSnapshot(LEncodeSnapshot* lir);
     void visitGetDynamicName(LGetDynamicName* lir);
     void visitFilterArgumentsOrEvalS(LFilterArgumentsOrEvalS* lir);
     void visitFilterArgumentsOrEvalV(LFilterArgumentsOrEvalV* lir);
-    void visitCallDirectEval(LCallDirectEval* lir);
+    void visitCallDirectEvalS(LCallDirectEvalS* lir);
+    void visitCallDirectEvalV(LCallDirectEvalV* lir);
     void visitDoubleToInt32(LDoubleToInt32* lir);
     void visitFloat32ToInt32(LFloat32ToInt32* lir);
     void visitNewArrayCallVM(LNewArray* lir);
     void visitNewArray(LNewArray* lir);
     void visitOutOfLineNewArray(OutOfLineNewArray* ool);
     void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
     void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
     void visitNewObjectVMCall(LNewObject* lir);
@@ -319,18 +315,16 @@ class CodeGenerator : public CodeGenerat
     void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
     void visitHasClass(LHasClass* lir);
     void visitAsmJSParameter(LAsmJSParameter* lir);
     void visitAsmJSReturn(LAsmJSReturn* ret);
     void visitAsmJSVoidReturn(LAsmJSVoidReturn* ret);
     void visitLexicalCheck(LLexicalCheck* ins);
     void visitThrowUninitializedLexical(LThrowUninitializedLexical* ins);
     void visitDebugger(LDebugger* ins);
-    void visitNewTarget(LNewTarget* ins);
-    void visitArrowNewTarget(LArrowNewTarget* ins);
 
     void visitCheckOverRecursed(LCheckOverRecursed* lir);
     void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
 
     void visitInterruptCheckImplicit(LInterruptCheckImplicit* ins);
     void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
 
     void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir);
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -357,23 +357,23 @@ JitRuntime::patchIonBackedges(JSRuntime*
             PatchBackedge(patchableBackedge->backedge, patchableBackedge->loopHeader, target);
         else
             PatchBackedge(patchableBackedge->backedge, patchableBackedge->interruptCheck, target);
     }
 }
 
 JitCompartment::JitCompartment()
   : stubCodes_(nullptr),
+    baselineCallReturnAddr_(nullptr),
     baselineGetPropReturnAddr_(nullptr),
     baselineSetPropReturnAddr_(nullptr),
     stringConcatStub_(nullptr),
     regExpExecStub_(nullptr),
     regExpTestStub_(nullptr)
 {
-    baselineCallReturnAddrs_[0] = baselineCallReturnAddrs_[1] = nullptr;
 }
 
 JitCompartment::~JitCompartment()
 {
     js_delete(stubCodes_);
 }
 
 bool
@@ -647,21 +647,18 @@ JitCompartment::sweep(FreeOp* fop, JSCom
     // do this for minor GCs.
     MOZ_ASSERT(!fop->runtime()->isHeapMinorCollecting());
     CancelOffThreadIonCompile(compartment, nullptr);
     FinishAllOffThreadCompilations(compartment);
 
     stubCodes_->sweep(fop);
 
     // If the sweep removed the ICCall_Fallback stub, nullptr the baselineCallReturnAddr_ field.
-    if (!stubCodes_->lookup(ICCall_Fallback::Compiler::CALL_KEY))
-        baselineCallReturnAddrs_[0] = nullptr;
-    if (!stubCodes_->lookup(ICCall_Fallback::Compiler::CONSTRUCT_KEY))
-        baselineCallReturnAddrs_[1] = nullptr;
-
+    if (!stubCodes_->lookup(static_cast<uint32_t>(ICStub::Call_Fallback)))
+        baselineCallReturnAddr_ = nullptr;
     // Similarly for the ICGetProp_Fallback stub.
     if (!stubCodes_->lookup(static_cast<uint32_t>(ICStub::GetProp_Fallback)))
         baselineGetPropReturnAddr_ = nullptr;
     if (!stubCodes_->lookup(static_cast<uint32_t>(ICStub::SetProp_Fallback)))
         baselineSetPropReturnAddr_ = nullptr;
 
     if (stringConcatStub_ && !IsMarkedUnbarriered(&stringConcatStub_))
         stringConcatStub_ = nullptr;
@@ -2557,32 +2554,28 @@ jit::SetEnterJitData(JSContext* cx, Ente
         data.maxArgc = Max(args.length(), numFormals) + 1;
         data.scopeChain = nullptr;
         data.calleeToken = CalleeToToken(&args.callee().as<JSFunction>(), data.constructing);
 
         if (data.numActualArgs >= numFormals) {
             data.maxArgv = args.base() + 1;
         } else {
             MOZ_ASSERT(vals.empty());
-            unsigned numPushedArgs = Max(args.length(), numFormals);
-            if (!vals.reserve(numPushedArgs + 1 + data.constructing))
+            if (!vals.reserve(Max(args.length() + 1, numFormals + 1)))
                 return false;
 
             // Append |this| and any provided arguments.
             for (size_t i = 1; i < args.length() + 2; ++i)
                 vals.infallibleAppend(args.base()[i]);
 
             // Pad missing arguments with |undefined|.
             while (vals.length() < numFormals + 1)
                 vals.infallibleAppend(UndefinedValue());
 
-            if (data.constructing)
-                vals.infallibleAppend(args.newTarget());
-
-            MOZ_ASSERT(vals.length() >= numFormals + 1 + data.constructing);
+            MOZ_ASSERT(vals.length() >= numFormals + 1);
             data.maxArgv = vals.begin();
         }
     } else {
         data.constructing = false;
         data.numActualArgs = 0;
         data.maxArgc = 1;
         data.maxArgv = state.asExecute()->addressOfThisv();
         data.scopeChain = state.asExecute()->scopeChain();
@@ -2590,32 +2583,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
@@ -2002,19 +2002,16 @@ IonBuilder::inspectOpcode(JSOp op)
 
       case JSOP_GIMPLICITTHIS:
         if (!script()->hasPollutedGlobalScope())
             return pushConstant(UndefinedValue());
 
         // Just fall through to the unsupported bytecode case.
         break;
 
-      case JSOP_NEWTARGET:
-        return jsop_newtarget();
-
 #ifdef DEBUG
       case JSOP_PUSHBLOCKSCOPE:
       case JSOP_FRESHENBLOCKSCOPE:
       case JSOP_POPBLOCKSCOPE:
         // These opcodes are currently unhandled by Ion, but in principle
         // there's no reason they couldn't be.  Whenever this happens, OSR will
         // have to consider that JSOP_FRESHENBLOCK mutates the scope chain --
         // right now it caches the scope chain in MBasicBlock::scopeChain().
@@ -5266,18 +5263,16 @@ IonBuilder::inlineCallsite(const ObjectV
         callInfo.fun()->setImplicitlyUsedUnchecked();
 
         // If the callee is not going to be a lambda (which may vary across
         // different invocations), then the callee definition can be replaced by a
         // constant.
         if (target->isSingleton()) {
             // Replace the function with an MConstant.
             MConstant* constFun = constant(ObjectValue(*target));
-            if (callInfo.constructing() && callInfo.getNewTarget() == callInfo.fun())
-                callInfo.setNewTarget(constFun);
             callInfo.setFun(constFun);
         }
 
         return inlineSingleCall(callInfo, target);
     }
 
     // Choose a subset of the targets for polymorphic inlining.
     BoolVector choiceSet(alloc());
@@ -6136,17 +6131,17 @@ IonBuilder::jsop_call(uint32_t argc, boo
         } else if (*GetNextPc(pc) == JSOP_POS) {
             // Note: this is lame, overspecialized on the code patterns used
             // by asm.js and should be replaced by a more general mechanism.
             // See bug 870847.
             observed->addType(TypeSet::DoubleType(), alloc_->lifoAlloc());
         }
     }
 
-    int calleeDepth = -((int)argc + 2 + constructing);
+    int calleeDepth = -((int)argc + 2);
 
     // Acquire known call target if existent.
     ObjectVector targets(alloc());
     TemporaryTypeSet* calleeTypes = current->peek(calleeDepth)->resultTypeSet();
     if (calleeTypes && !getPolyCallTargets(calleeTypes, constructing, targets, 4))
         return false;
 
     CallInfo callInfo(alloc(), constructing);
@@ -6279,24 +6274,21 @@ IonBuilder::makeCallHelper(JSFunction* t
             thisTypes->getKnownMIRType() == MIRType_Object &&
             thisTypes->isDOMClass(constraints()) &&
             testShouldDOMCall(thisTypes, target, JSJitInfo::Method))
         {
             isDOMCall = true;
         }
     }
 
-    MCall* call = MCall::New(alloc(), target, targetArgs + 1 + callInfo.constructing(),
-                             callInfo.argc(), callInfo.constructing(), isDOMCall);
+    MCall* call = MCall::New(alloc(), target, targetArgs + 1, callInfo.argc(),
+                             callInfo.constructing(), isDOMCall);
     if (!call)
         return nullptr;
 
-    if (callInfo.constructing())
-        call->addArg(targetArgs + 1, callInfo.getNewTarget());
-
     // Explicitly pad any missing arguments with |undefined|.
     // This permits skipping the argumentsRectifier.
     for (int i = targetArgs; i > (int)callInfo.argc(); i--) {
         MOZ_ASSERT_IF(target, !target->isNative());
         MConstant* undef = constant(UndefinedValue());
         call->addArg(i, undef);
     }
 
@@ -6422,20 +6414,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 +6442,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);
@@ -9429,50 +9416,16 @@ IonBuilder::jsop_arguments()
         return true;
     }
     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 (info().funMaybeLazy()->isArrow()) {
-        MArrowNewTarget* arrowNewTarget = MArrowNewTarget::New(alloc(), getCallee());
-        current->add(arrowNewTarget);
-        current->push(arrowNewTarget);
-        return true;
-    }
-
-    if (inliningDepth_ == 0) {
-        MNewTarget* newTarget = MNewTarget::New(alloc());
-        current->add(newTarget);
-        current->push(newTarget);
-        return true;
-    }
-
-    if (!info().constructing()) {
-        pushConstant(UndefinedValue());
-        return true;
-    }
-
-    current->push(inlineCallInfo_->getNewTarget());
-    return true;
-}
-
-bool
 IonBuilder::jsop_rest()
 {
     ArrayObject* templateObject = &inspector->getTemplateObject(pc)->as<ArrayObject>();
 
     if (inliningDepth_ == 0) {
         // We don't know anything about the callee.
         MArgumentsLength* numActuals = MArgumentsLength::New(alloc());
         current->add(numActuals);
@@ -9482,17 +9435,17 @@ IonBuilder::jsop_rest()
         MRest* rest = MRest::New(alloc(), constraints(), numActuals, info().nargs() - 1,
                                  templateObject);
         current->add(rest);
         current->push(rest);
         return true;
     }
 
     // We know the exact number of arguments the callee pushed.
-    unsigned numActuals = inlineCallInfo_->argc();
+    unsigned numActuals = inlineCallInfo_->argv().length();
     unsigned numFormals = info().nargs() - 1;
     unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0;
 
     MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject);
     current->add(templateConst);
 
     MNewArray* array = MNewArray::New(alloc(), constraints(), numRest, templateConst,
                                       templateObject->group()->initialHeap(constraints()),
@@ -11882,21 +11835,20 @@ IonBuilder::jsop_lambda(JSFunction* fun)
 
 bool
 IonBuilder::jsop_lambda_arrow(JSFunction* fun)
 {
     MOZ_ASSERT(analysis().usesScopeChain());
     MOZ_ASSERT(fun->isArrow());
     MOZ_ASSERT(!fun->isNative());
 
-    MDefinition* newTargetDef = current->pop();
     MDefinition* thisDef = current->pop();
 
     MLambdaArrow* ins = MLambdaArrow::New(alloc(), constraints(), current->scopeChain(),
-                                          thisDef, newTargetDef, fun);
+                                          thisDef, fun);
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_setarg(uint32_t arg)
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -702,17 +702,16 @@ class IonBuilder
     bool jsop_isnoiter();
     bool jsop_iterend();
     bool jsop_in();
     bool jsop_in_dense();
     bool jsop_instanceof();
     bool jsop_getaliasedvar(ScopeCoordinate sc);
     bool jsop_setaliasedvar(ScopeCoordinate sc);
     bool jsop_debugger();
-    bool jsop_newtarget();
 
     /* Inlining. */
 
     enum InliningStatus
     {
         InliningStatus_Error,
         InliningStatus_NotInlined,
         InliningStatus_WarmUpCountTooLow,
@@ -1240,57 +1239,48 @@ class IonBuilder
     void trackOptimizationSuccessUnchecked();
     void trackInlineSuccessUnchecked(InliningStatus status);
 };
 
 class CallInfo
 {
     MDefinition* fun_;
     MDefinition* thisArg_;
-    MDefinition* newTargetArg_;
     MDefinitionVector args_;
 
     bool constructing_;
     bool setter_;
 
   public:
     CallInfo(TempAllocator& alloc, bool constructing)
       : fun_(nullptr),
         thisArg_(nullptr),
-        newTargetArg_(nullptr),
         args_(alloc),
         constructing_(constructing),
         setter_(false)
     { }
 
     bool init(CallInfo& callInfo) {
         MOZ_ASSERT(constructing_ == callInfo.constructing());
 
         fun_ = callInfo.fun();
         thisArg_ = callInfo.thisArg();
 
-        if (constructing())
-            newTargetArg_ = callInfo.getNewTarget();
-
         if (!args_.appendAll(callInfo.argv()))
             return false;
 
         return true;
     }
 
     bool init(MBasicBlock* current, uint32_t argc) {
         MOZ_ASSERT(args_.empty());
 
         // Get the arguments in the right order
         if (!args_.reserve(argc))
             return false;
-
-        if (constructing())
-            setNewTarget(current->pop());
-
         for (int32_t i = argc; i > 0; i--)
             args_.infallibleAppend(current->peek(-i));
         current->popn(argc);
 
         // Get |this| and |fun|
         setThis(current->pop());
         setFun(current->pop());
 
@@ -1302,26 +1292,23 @@ class CallInfo
     }
 
     void pushFormals(MBasicBlock* current) {
         current->push(fun());
         current->push(thisArg());
 
         for (uint32_t i = 0; i < argc(); i++)
             current->push(getArg(i));
-
-        if (constructing())
-            current->push(getNewTarget());
     }
 
     uint32_t argc() const {
         return args_.length();
     }
     uint32_t numFormals() const {
-        return argc() + 2 + constructing();
+        return argc() + 2;
     }
 
     bool setArgs(const MDefinitionVector& args) {
         MOZ_ASSERT(args_.empty());
         return args_.appendAll(args);
     }
 
     MDefinitionVector& argv() {
@@ -1357,25 +1344,16 @@ class CallInfo
     void setThis(MDefinition* thisArg) {
         thisArg_ = thisArg;
     }
 
     bool constructing() const {
         return constructing_;
     }
 
-    void setNewTarget(MDefinition* newTarget) {
-        MOZ_ASSERT(constructing());
-        newTargetArg_ = newTarget;
-    }
-    MDefinition* getNewTarget() const {
-        MOZ_ASSERT(newTargetArg_);
-        return newTargetArg_;
-    }
-
     bool isSetter() const {
         return setter_;
     }
     void markAsSetter() {
         setter_ = true;
     }
 
     MDefinition* fun() const {
@@ -1385,18 +1363,16 @@ class CallInfo
 
     void setFun(MDefinition* fun) {
         fun_ = fun;
     }
 
     void setImplicitlyUsedUnchecked() {
         fun_->setImplicitlyUsedUnchecked();
         thisArg_->setImplicitlyUsedUnchecked();
-        if (newTargetArg_)
-            newTargetArg_->setImplicitlyUsedUnchecked();
         for (uint32_t i = 0; i < argc(); i++)
             getArg(i)->setImplicitlyUsedUnchecked();
     }
 };
 
 bool NeedsPostBarrier(CompileInfo& info, MDefinition* value);
 
 } // namespace jit
--- a/js/src/jit/JitCompartment.h
+++ b/js/src/jit/JitCompartment.h
@@ -417,17 +417,17 @@ class JitCompartment
     friend class JitActivation;
 
     // Map ICStub keys to ICStub shared code objects.
     typedef WeakValueCache<uint32_t, ReadBarrieredJitCode> ICStubCodeMap;
     ICStubCodeMap* stubCodes_;
 
     // Keep track of offset into various baseline stubs' code at return
     // point from called script.
-    void* baselineCallReturnAddrs_[2];
+    void* baselineCallReturnAddr_;
     void* baselineGetPropReturnAddr_;
     void* baselineSetPropReturnAddr_;
 
     // Stubs to concatenate two strings inline, or perform RegExp calls inline.
     // These bake in zone and compartment specific pointers and can't be stored
     // in JitRuntime. These are weak pointers, but are not declared as
     // ReadBarriered since they are only read from during Ion compilation,
     // which may occur off thread and whose barriers are captured during
@@ -476,23 +476,23 @@ class JitCompartment
     bool putStubCode(uint32_t key, Handle<JitCode*> stubCode) {
         // Make sure to do a lookupForAdd(key) and then insert into that slot, because
         // that way if stubCode gets moved due to a GC caused by lookupForAdd, then
         // we still write the correct pointer.
         MOZ_ASSERT(!stubCodes_->has(key));
         ICStubCodeMap::AddPtr p = stubCodes_->lookupForAdd(key);
         return stubCodes_->add(p, key, stubCode.get());
     }
-    void initBaselineCallReturnAddr(void* addr, bool constructing) {
-        MOZ_ASSERT(baselineCallReturnAddrs_[constructing] == nullptr);
-        baselineCallReturnAddrs_[constructing] = addr;
+    void initBaselineCallReturnAddr(void* addr) {
+        MOZ_ASSERT(baselineCallReturnAddr_ == nullptr);
+        baselineCallReturnAddr_ = addr;
     }
-    void* baselineCallReturnAddr(bool constructing) {
-        MOZ_ASSERT(baselineCallReturnAddrs_[constructing] != nullptr);
-        return baselineCallReturnAddrs_[constructing];
+    void* baselineCallReturnAddr() {
+        MOZ_ASSERT(baselineCallReturnAddr_ != nullptr);
+        return baselineCallReturnAddr_;
     }
     void initBaselineGetPropReturnAddr(void* addr) {
         MOZ_ASSERT(baselineGetPropReturnAddr_ == nullptr);
         baselineGetPropReturnAddr_ = addr;
     }
     void* baselineGetPropReturnAddr() {
         MOZ_ASSERT(baselineGetPropReturnAddr_ != nullptr);
         return baselineGetPropReturnAddr_;
--- 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);
@@ -741,39 +741,38 @@ class InlineFrameIterator
                     // need to take them from there.
 
                     // The overflown arguments are not available in current frame.
                     // They are the last pushed arguments in the parent frame of
                     // this inlined frame.
                     InlineFrameIterator it(cx, this);
                     ++it;
                     unsigned argsObjAdj = it.script()->argumentsHasVarBinding() ? 1 : 0;
-                    bool hasNewTarget = isConstructing();
                     SnapshotIterator parent_s(it.snapshotIterator());
 
                     // Skip over all slots until we get to the last slots
                     // (= arguments slots of callee) the +3 is for [this], [returnvalue],
                     // [scopechain], and maybe +1 for [argsObj]
-                    MOZ_ASSERT(parent_s.numAllocations() >= nactual + 3 + argsObjAdj + hasNewTarget);
-                    unsigned skip = parent_s.numAllocations() - nactual - 3 - argsObjAdj - hasNewTarget;
+                    MOZ_ASSERT(parent_s.numAllocations() >= nactual + 3 + argsObjAdj);
+                    unsigned skip = parent_s.numAllocations() - nactual - 3 - argsObjAdj;
                     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/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -1029,19 +1029,18 @@ MarkThisAndArguments(JSTracer* trc, JitF
         nformals = fun->nonLazyScript()->argumentsHasVarBinding() ? 0 : fun->nargs();
     }
 
     Value* argv = layout->argv();
 
     // Trace |this|.
     TraceRoot(trc, argv, "ion-thisv");
 
-    // Trace actual arguments and newTarget beyond the formals. Note + 1 for thisv.
-    bool constructing = CalleeTokenIsConstructing(layout->calleeToken());
-    for (size_t i = nformals + 1; i < nargs + 1 + constructing; i++)
+    // Trace actual arguments beyond the formals. Note + 1 for thisv.
+    for (size_t i = nformals + 1; i < nargs + 1; i++)
         TraceRoot(trc, &argv[i], "ion-argv");
 }
 
 static void
 MarkThisAndArguments(JSTracer* trc, const JitFrameIterator& frame)
 {
     JitFrameLayout* layout = frame.jsFrame();
     MarkThisAndArguments(trc, layout);
@@ -2441,18 +2440,17 @@ InlineFrameIterator::findNextFrame()
         } else if (IsSetPropPC(pc_)) {
             numActualArgs_ = 1;
         }
 
         if (numActualArgs_ == 0xbadbad)
             MOZ_CRASH("Couldn't deduce the number of arguments of an ionmonkey frame");
 
         // Skip over non-argument slots, as well as |this|.
-        bool skipNewTarget = JSOp(*pc_) == JSOP_NEW;
-        unsigned skipCount = (si_.numAllocations() - 1) - numActualArgs_ - 1 - skipNewTarget;
+        unsigned skipCount = (si_.numAllocations() - 1) - numActualArgs_ - 1;
         for (unsigned j = 0; j < skipCount; j++)
             si_.skip();
 
         // This value should correspond to the function which is being inlined.
         // The value must be readable to iterate over the inline frame. Most of
         // the time, these functions are stored as JSFunction constants,
         // register which are holding the JSFunction pointer, or recover
         // instruction with Default value.
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -1528,20 +1528,16 @@ class LJSCallInstructionHelper : public 
     JSFunction* getSingleTarget() const {
         return mir()->getSingleTarget();
     }
 
     // Does not include |this|.
     uint32_t numActualArgs() const {
         return mir()->numActualArgs();
     }
-
-    bool isConstructing() const {
-        return mir()->isConstructing();
-    }
 };
 
 // Generates a polymorphic callsite, wherein the function being called is
 // unknown and anticipated to vary.
 class LCallGeneric : public LJSCallInstructionHelper<BOX_PIECES, 1, 2>
 {
   public:
     LIR_HEADER(CallGeneric)
@@ -1922,42 +1918,63 @@ 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>
-{
-  public:
-    LIR_HEADER(CallDirectEval)
-
-    LCallDirectEval(const LAllocation& scopeChain, const LAllocation& string)
+class LCallDirectEvalS : public LCallInstructionHelper<BOX_PIECES, 2 + BOX_PIECES, 0>
+{
+  public:
+    LIR_HEADER(CallDirectEvalS)
+
+    LCallDirectEvalS(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);
     }
     const LAllocation* getString() {
         return getOperand(1);
     }
 };
 
+class LCallDirectEvalV : public LCallInstructionHelper<BOX_PIECES, 1 + (2 * BOX_PIECES), 0>
+{
+  public:
+    LIR_HEADER(CallDirectEvalV)
+
+    explicit LCallDirectEvalV(const LAllocation& scopeChain)
+    {
+        setOperand(0, scopeChain);
+    }
+
+    static const size_t Argument = 1;
+    static const size_t ThisValue = 1 + BOX_PIECES;
+
+    MCallDirectEval* mir() const {
+        return mir_->toCallDirectEval();
+    }
+
+    const LAllocation* getScopeChain() {
+        return getOperand(0);
+    }
+};
+
 // Takes in either an integer or boolean input and tests it for truthiness.
 class LTestIAndBranch : public LControlInstructionHelper<2, 1, 0>
 {
   public:
     LIR_HEADER(TestIAndBranch)
 
     LTestIAndBranch(const LAllocation& in, MBasicBlock* ifTrue, MBasicBlock* ifFalse)
     {
@@ -4002,23 +4019,22 @@ class LLambda : public LInstructionHelpe
     const LDefinition* temp() {
         return getTemp(0);
     }
     const MLambda* mir() const {
         return mir_->toLambda();
     }
 };
 
-class LLambdaArrow : public LInstructionHelper<1, 1 + (2 * BOX_PIECES), 1>
+class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 1>
 {
   public:
     LIR_HEADER(LambdaArrow)
 
     static const size_t ThisValue = 1;
-    static const size_t NewTargetValue = ThisValue + BOX_PIECES;
 
     LLambdaArrow(const LAllocation& scopeChain, const LDefinition& temp) {
         setOperand(0, scopeChain);
         setTemp(0, temp);
     }
     const LAllocation* scopeChain() {
         return getOperand(0);
     }
@@ -7028,32 +7044,12 @@ class LDebugger : public LCallInstructio
     LIR_HEADER(Debugger)
 
     LDebugger(const LDefinition& temp1, const LDefinition& temp2) {
         setTemp(0, temp1);
         setTemp(1, temp2);
     }
 };
 
-class LNewTarget : public LInstructionHelper<BOX_PIECES, 0, 0>
-{
-  public:
-    LIR_HEADER(NewTarget)
-};
-
-class LArrowNewTarget : public LInstructionHelper<BOX_PIECES, 1, 0>
-{
-  public:
-    explicit LArrowNewTarget(const LAllocation& callee) {
-        setOperand(0, callee);
-    }
-
-    LIR_HEADER(ArrowNewTarget)
-
-    const LAllocation* callee() {
-        return getOperand(0);
-    }
-};
-
 } // namespace jit
 } // namespace js
 
 #endif /* jit_LIR_Common_h */
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -71,17 +71,18 @@
     _(CallNative)                   \
     _(ApplyArgsGeneric)             \
     _(Bail)                         \
     _(Unreachable)                  \
     _(EncodeSnapshot)               \
     _(GetDynamicName)               \
     _(FilterArgumentsOrEvalS)       \
     _(FilterArgumentsOrEvalV)       \
-    _(CallDirectEval)               \
+    _(CallDirectEvalS)              \
+    _(CallDirectEvalV)              \
     _(StackArgT)                    \
     _(StackArgV)                    \
     _(CreateThis)                   \
     _(CreateThisWithProto)          \
     _(CreateThisWithTemplate)       \
     _(CreateArgumentsObject)        \
     _(GetArgumentsObjectArg)        \
     _(SetArgumentsObjectArg)        \
@@ -344,19 +345,17 @@
     _(AssertRangeD)                 \
     _(AssertRangeF)                 \
     _(AssertRangeV)                 \
     _(AssertResultV)                \
     _(AssertResultT)                \
     _(LexicalCheck)                 \
     _(ThrowUninitializedLexical)    \
     _(NurseryObject)                \
-    _(Debugger)                     \
-    _(NewTarget)                    \
-    _(ArrowNewTarget)
+    _(Debugger)
 
 #if defined(JS_CODEGEN_X86)
 # include "jit/x86/LOpcodes-x86.h"
 #elif defined(JS_CODEGEN_X64)
 # include "jit/x64/LOpcodes-x64.h"
 #elif defined(JS_CODEGEN_ARM)
 # include "jit/arm/LOpcodes-arm.h"
 #elif defined(JS_CODEGEN_MIPS)
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -381,26 +381,16 @@ LIRGenerator::visitLoadArrowThis(MLoadAr
     MOZ_ASSERT(ins->type() == MIRType_Value);
     MOZ_ASSERT(ins->callee()->type() == MIRType_Object);
 
     LLoadArrowThis* lir = new(alloc()) LLoadArrowThis(useRegister(ins->callee()));
     defineBox(lir, ins);
 }
 
 void
-LIRGenerator::visitArrowNewTarget(MArrowNewTarget* ins)
-{
-    MOZ_ASSERT(ins->type() == MIRType_Value);
-    MOZ_ASSERT(ins->callee()->type() == MIRType_Object);
-
-    LArrowNewTarget* lir = new(alloc()) LArrowNewTarget(useRegister(ins->callee()));
-    defineBox(lir, ins);
-}
-
-void
 LIRGenerator::lowerCallArguments(MCall* call)
 {
     uint32_t argc = call->numStackArgs();
 
     // Align the arguments of a call such that the callee would keep the same
     // alignment as the caller.
     uint32_t baseSlot = 0;
     if (JitStackValueAlignment > 1)
@@ -611,25 +601,34 @@ LIRGenerator::visitFilterArgumentsOrEval
 
 void
 LIRGenerator::visitCallDirectEval(MCallDirectEval* ins)
 {
     MDefinition* scopeChain = ins->getScopeChain();
     MOZ_ASSERT(scopeChain->type() == MIRType_Object);
 
     MDefinition* string = ins->getString();
-    MOZ_ASSERT(string->type() == MIRType_String);
+    MOZ_ASSERT(string->type() == MIRType_String || string->type() == MIRType_Value);
 
     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);
+
+
+    LInstruction* lir;
+    if (string->type() == MIRType_String) {
+        lir = new(alloc()) LCallDirectEvalS(useRegisterAtStart(scopeChain),
+                                            useRegisterAtStart(string));
+    } else {
+        lir = new(alloc()) LCallDirectEvalV(useRegisterAtStart(scopeChain));
+        useBoxAtStart(lir, LCallDirectEvalV::Argument, string);
+    }
+
+    if (string->type() == MIRType_String)
+        useBoxAtStart(lir, LCallDirectEvalS::ThisValue, thisValue);
+    else
+        useBoxAtStart(lir, LCallDirectEvalV::ThisValue, thisValue);
 
     defineReturn(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 static JSOp
 ReorderComparison(JSOp op, MDefinition** lhsp, MDefinition** rhsp)
 {
@@ -2160,21 +2159,19 @@ LIRGenerator::visitLambda(MLambda* ins)
     }
 }
 
 void
 LIRGenerator::visitLambdaArrow(MLambdaArrow* ins)
 {
     MOZ_ASSERT(ins->scopeChain()->type() == MIRType_Object);
     MOZ_ASSERT(ins->thisDef()->type() == MIRType_Value);
-    MOZ_ASSERT(ins->newTargetDef()->type() == MIRType_Value);
 
     LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain()), temp());
     useBox(lir, LLambdaArrow::ThisValue, ins->thisDef());
-    useBox(lir, LLambdaArrow::NewTargetValue, ins->newTargetDef());
     define(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
 LIRGenerator::visitKeepAliveObject(MKeepAliveObject* ins)
 {
     MDefinition* obj = ins->object();
@@ -3559,23 +3556,16 @@ LIRGenerator::visitArgumentsLength(MArgu
 void
 LIRGenerator::visitGetFrameArgument(MGetFrameArgument* ins)
 {
     LGetFrameArgument* lir = new(alloc()) LGetFrameArgument(useRegisterOrConstant(ins->index()));
     defineBox(lir, ins);
 }
 
 void
-LIRGenerator::visitNewTarget(MNewTarget* ins)
-{
-    LNewTarget* lir = new(alloc()) LNewTarget();
-    defineBox(lir, ins);
-}
-
-void
 LIRGenerator::visitSetFrameArgument(MSetFrameArgument* ins)
 {
     MDefinition* input = ins->input();
 
     if (input->type() == MIRType_Value) {
         LSetFrameArgumentV* lir = new(alloc()) LSetFrameArgumentV();
         useBox(lir, LSetFrameArgumentV::Input, input);
         add(lir, ins);
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -292,16 +292,14 @@ class LIRGenerator : public LIRGenerator
     void visitBeta(MBeta* ins);
     void visitObjectState(MObjectState* ins);
     void visitArrayState(MArrayState* ins);
     void visitUnknownValue(MUnknownValue* ins);
     void visitLexicalCheck(MLexicalCheck* ins);
     void visitThrowUninitializedLexical(MThrowUninitializedLexical* ins);
     void visitDebugger(MDebugger* ins);
     void visitNurseryObject(MNurseryObject* ins);
-    void visitNewTarget(MNewTarget* ins);
-    void visitArrowNewTarget(MArrowNewTarget* ins);
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_Lowering_h */
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -2877,21 +2877,19 @@ IonBuilder::inlineBoundFunction(CallInfo
     if (!target->getBoundFunctionTarget()->is<JSFunction>())
         return InliningStatus_NotInlined;
 
     JSFunction* scriptedTarget = &(target->getBoundFunctionTarget()->as<JSFunction>());
 
     // Don't optimize if we're constructing and the callee is not a
     // constructor, so that CallKnown does not have to handle this case
     // (it should always throw).
-    if (nativeCallInfo.constructing() && !scriptedTarget->isConstructor())
+    if (nativeCallInfo.constructing() && !scriptedTarget->isConstructor()) {
         return InliningStatus_NotInlined;
-
-    if (nativeCallInfo.constructing() && nativeCallInfo.getNewTarget() != nativeCallInfo.fun())
-        return InliningStatus_NotInlined;
+    }
 
     if (gc::IsInsideNursery(scriptedTarget))
         return InliningStatus_NotInlined;
 
     for (size_t i = 0; i < target->getBoundFunctionArgumentCount(); i++) {
         const Value val = target->getBoundFunctionArgument(i);
         if (val.isObject() && gc::IsInsideNursery(&val.toObject()))
             return InliningStatus_NotInlined;
@@ -2920,21 +2918,16 @@ IonBuilder::inlineBoundFunction(CallInfo
 
     for (size_t i = 0; i < target->getBoundFunctionArgumentCount(); i++) {
         MConstant* argConst = constant(target->getBoundFunctionArgument(i));
         callInfo.argv().infallibleAppend(argConst);
     }
     for (size_t i = 0; i < nativeCallInfo.argc(); i++)
         callInfo.argv().infallibleAppend(nativeCallInfo.getArg(i));
 
-    // We only inline when it was not a super-call, so just set the newTarget
-    // to be the target function, per spec.
-    if (nativeCallInfo.constructing())
-        callInfo.setNewTarget(callInfo.fun());
-
     if (!makeCall(scriptedTarget, callInfo))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineAtomicsCompareExchange(CallInfo& callInfo)
--- 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>,
-                      StringPolicy<1>,
-                      BoxPolicy<2>,
-                      BoxPolicy<3> >::Data
+  : public MAryInstruction<3>,
+    public Mix3Policy<ObjectPolicy<0>,
+                      BoxExceptPolicy<1, MIRType_String>,
+                      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;
     }
@@ -6702,46 +6697,16 @@ class MLoadArrowThis
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const override {
         // An arrow function's lexical |this| value is immutable.
         return AliasSet::None();
     }
 };
 
-// Load an arrow function's |new.target| value.
-class MArrowNewTarget
-  : public MUnaryInstruction,
-    public SingleObjectPolicy::Data
-{
-    explicit MArrowNewTarget(MDefinition* callee)
-      : MUnaryInstruction(callee)
-    {
-        setResultType(MIRType_Value);
-        setMovable();
-    }
-
-  public:
-    INSTRUCTION_HEADER(ArrowNewTarget)
-
-    static MArrowNewTarget* New(TempAllocator& alloc, MDefinition* callee) {
-        return new(alloc) MArrowNewTarget(callee);
-    }
-    MDefinition* callee() const {
-        return getOperand(0);
-    }
-    bool congruentTo(const MDefinition* ins) const override {
-        return congruentIfOperandsEqual(ins);
-    }
-    AliasSet getAliasSet() const override {
-        // An arrow function's lexical |this| value is immutable.
-        return AliasSet::None();
-    }
-};
-
 class MPhi final
   : public MDefinition,
     public InlineListNode<MPhi>,
     public NoTypePolicy::Data
 {
     js::Vector<MUse, 2, JitAllocPolicy> inputs_;
 
     TruncateKind truncateKind_;
@@ -7564,49 +7529,45 @@ class MLambda
     }
     bool writeRecoverData(CompactBufferWriter& writer) const override;
     bool canRecoverOnBailout() const override {
         return true;
     }
 };
 
 class MLambdaArrow
-  : public MTernaryInstruction,
-    public Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, BoxPolicy<2> >::Data
+  : public MBinaryInstruction,
+    public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >::Data
 {
     const LambdaFunctionInfo info_;
 
     MLambdaArrow(CompilerConstraintList* constraints, MDefinition* scopeChain,
-                 MDefinition* this_, MDefinition* newTarget_, JSFunction* fun)
-      : MTernaryInstruction(scopeChain, this_, newTarget_), info_(fun)
+                 MDefinition* this_, JSFunction* fun)
+      : MBinaryInstruction(scopeChain, this_), info_(fun)
     {
         setResultType(MIRType_Object);
         MOZ_ASSERT(!ObjectGroup::useSingletonForClone(fun));
         if (!fun->isSingleton())
             setResultTypeSet(MakeSingletonTypeSet(constraints, fun));
     }
 
   public:
     INSTRUCTION_HEADER(LambdaArrow)
 
     static MLambdaArrow* New(TempAllocator& alloc, CompilerConstraintList* constraints,
-                             MDefinition* scopeChain, MDefinition* this_, MDefinition* newTarget_,
-                             JSFunction* fun)
-    {
-        return new(alloc) MLambdaArrow(constraints, scopeChain, this_, newTarget_, fun);
+                             MDefinition* scopeChain, MDefinition* this_, JSFunction* fun)
+    {
+        return new(alloc) MLambdaArrow(constraints, scopeChain, this_, fun);
     }
     MDefinition* scopeChain() const {
         return getOperand(0);
     }
     MDefinition* thisDef() const {
         return getOperand(1);
     }
-    MDefinition* newTargetDef() const {
-        return getOperand(2);
-    }
     const LambdaFunctionInfo& info() const {
         return info_;
     }
 };
 
 // Returns obj->slots.
 class MSlots
   : public MUnaryInstruction,
@@ -12061,38 +12022,16 @@ class MGetFrameArgument
         // If the script doesn't have any JSOP_SETARG ops, then this instruction is never
         // aliased.
         if (scriptHasSetArg_)
             return AliasSet::Load(AliasSet::FrameArgument);
         return AliasSet::None();
     }
 };
 
-class MNewTarget : public MNullaryInstruction
-{
-    MNewTarget() : MNullaryInstruction() {
-        setResultType(MIRType_Value);
-        setMovable();
-    }
-
-  public:
-    INSTRUCTION_HEADER(NewTarget)
-
-    static MNewTarget* New(TempAllocator& alloc) {
-        return new(alloc) MNewTarget();
-    }
-
-    bool congruentTo(const MDefinition* ins) const override {
-        return congruentIfOperandsEqual(ins);
-    }
-    AliasSet getAliasSet() const override {
-        return AliasSet::None();
-    }
-};
-
 // This MIR instruction is used to set an argument value in the frame.
 class MSetFrameArgument
   : public MUnaryInstruction,
     public NoFloatPolicy<0>::Data
 {
     uint32_t argno_;
 
     MSetFrameArgument(uint32_t argno, MDefinition* value)
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -263,19 +263,17 @@ namespace jit {
     _(NewDerivedTypedObject)                                                \
     _(RecompileCheck)                                                       \
     _(MemoryBarrier)                                                        \
     _(AsmJSCompareExchangeHeap)                                             \
     _(AsmJSAtomicBinopHeap)                                                 \
     _(UnknownValue)                                                         \
     _(LexicalCheck)                                                         \
     _(ThrowUninitializedLexical)                                            \
-    _(Debugger)                                                             \
-    _(NewTarget)                                                            \
-    _(ArrowNewTarget)
+    _(Debugger)
 
 // Forward declarations of MIR types.
 #define FORWARD_DECLARE(op) class M##op;
  MIR_OPCODE_LIST(FORWARD_DECLARE)
 #undef FORWARD_DECLARE
 
 class MDefinitionVisitor // interface i.e. pure abstract class
 {
--- 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,25 +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 (callee()->isArrow())
-            return callee()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
-        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
@@ -1138,26 +1138,25 @@ FilterTypeSetPolicy::adjustInputs(TempAl
     _(BoxPolicy<0>)                                                     \
     _(ConvertToInt32Policy<0>)                                          \
     _(ConvertToStringPolicy<0>)                                         \
     _(ConvertToStringPolicy<2>)                                         \
     _(DoublePolicy<0>)                                                  \
     _(FloatingPointPolicy<0>)                                           \
     _(IntPolicy<0>)                                                     \
     _(IntPolicy<1>)                                                     \
-    _(Mix3Policy<ObjectPolicy<0>, StringPolicy<1>, BoxPolicy<2> >) \
+    _(Mix3Policy<ObjectPolicy<0>, BoxExceptPolicy<1, MIRType_String>, BoxPolicy<2> >) \
     _(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.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -52,31 +52,30 @@ VMFunction::addToFunctions()
         initialized = true;
         functions = nullptr;
     }
     this->next = functions;
     functions = this;
 }
 
 bool
-InvokeFunction(JSContext* cx, HandleObject obj, bool constructing, uint32_t argc, Value* argv,
-               Value* rval)
+InvokeFunction(JSContext* cx, HandleObject obj, uint32_t argc, Value* argv, Value* rval)
 {
-    AutoArrayRooter argvRoot(cx, argc + 1 + constructing, argv);
+    AutoArrayRooter argvRoot(cx, argc + 1, argv);
 
     // Data in the argument vector is arranged for a JIT -> JIT call.
     Value thisv = argv[0];
     Value* argvWithoutThis = argv + 1;
 
     // For constructing functions, |this| is constructed at caller side and we can just call Invoke.
     // When creating this failed / is impossible at caller site, i.e. MagicValue(JS_IS_CONSTRUCTING),
     // we use InvokeConstructor that creates it at the callee side.
     RootedValue rv(cx);
     if (thisv.isMagic(JS_IS_CONSTRUCTING)) {
-        if (!InvokeConstructor(cx, ObjectValue(*obj), argc, argvWithoutThis, true, &rv))
+        if (!InvokeConstructor(cx, ObjectValue(*obj), argc, argvWithoutThis, &rv))
             return false;
     } else {
         if (!Invoke(cx, thisv, ObjectValue(*obj), argc, argvWithoutThis, &rv))
             return false;
     }
 
     if (obj->is<JSFunction>()) {
         jsbytecode* pc;
@@ -84,25 +83,16 @@ InvokeFunction(JSContext* cx, HandleObje
         TypeScript::Monitor(cx, script, pc, rv.get());
     }
 
     *rval = rv;
     return true;
 }
 
 bool
-InvokeFunctionShuffleNewTarget(JSContext* cx, HandleObject obj, uint32_t numActualArgs,
-                               uint32_t numFormalArgs, Value* argv, Value* rval)
-{
-    MOZ_ASSERT(numFormalArgs > numActualArgs);
-    argv[1 + numActualArgs] = argv[1 + numFormalArgs];
-    return InvokeFunction(cx, obj, true, numActualArgs, argv, rval);
-}
-
-bool
 CheckOverRecursed(JSContext* cx)
 {
     // We just failed the jitStackLimit check. There are two possible reasons:
     //  - jitStackLimit was the real stack limit and we're over-recursed
     //  - jitStackLimit was set to UINTPTR_MAX by JSRuntime::requestInterrupt
     //    and we need to call JSRuntime::handleInterrupt.
 #if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
     JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, 0, return false);
--- 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
@@ -634,20 +626,17 @@ class AutoDetectInvalidation
     }
 
     ~AutoDetectInvalidation() {
         if (!disabled_ && ionScript_->invalidated())
             setReturnOverride();
     }
 };
 
-bool InvokeFunction(JSContext* cx, HandleObject obj0, bool constructing, uint32_t argc,
-                    Value* argv, Value* rval);
-bool InvokeFunctionShuffleNewTarget(JSContext* cx, HandleObject obj, uint32_t numActualArgs,
-                                    uint32_t numFormalArgs, Value* argv, Value* rval);
+bool InvokeFunction(JSContext* cx, HandleObject obj0, uint32_t argc, Value* argv, Value* rval);
 
 bool CheckOverRecursed(JSContext* cx);
 bool CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame,
                                 uint32_t extra, uint32_t earlyCheck);
 
 bool DefVarOrConst(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain);
 bool SetConst(JSContext* cx, HandlePropertyName name, HandleObject scopeChain, HandleValue rval);
 bool MutatePrototype(JSContext* cx, HandlePlainObject obj, HandleValue value);
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -147,26 +147,16 @@ JitRuntime::generateEnterJIT(JSContext* 
     // Save stack pointer.
     if (type == EnterJitBaseline)
         masm.movePtr(sp, r11);
 
     // Load the number of actual arguments into r10.
     masm.loadPtr(slot_vp, r10);
     masm.unboxInt32(Address(r10, 0), r10);
 
-    {
-        Label noNewTarget;
-        masm.branchTest32(Assembler::Zero, r9, Imm32(CalleeToken_FunctionConstructing),
-                          &noNewTarget);
-
-        masm.add32(Imm32(1), r1);
-
-        masm.bind(&noNewTarget);
-    }
-
     // Guarantee stack alignment of Jit frames.
     //
     // This code moves the stack pointer to the location where it should be when
     // we enter the Jit frame.  It moves the stack pointer such that we have
     // enough space reserved for pushing the arguments, and the JitFrameLayout.
     // The stack pointer is also aligned on the alignment expected by the Jit
     // frames.
     //
@@ -470,48 +460,36 @@ JitRuntime::generateArgumentsRectifier(J
 
     // Load the number of |undefined|s to push into r6.
     masm.ma_ldr(DTRAddr(sp, DtrOffImm(RectifierFrameLayout::offsetOfCalleeToken())), r1);
     masm.ma_and(Imm32(CalleeTokenMask), r1, r6);
     masm.ma_ldrh(EDtrAddr(r6, EDtrOffImm(JSFunction::offsetOfNargs())), r6);
 
     masm.ma_sub(r6, r8, r2);
 
-    // Get the topmost argument.
-    masm.ma_alu(sp, lsl(r8, 3), r3, OpAdd); // r3 <- r3 + nargs * 8
-    masm.ma_add(r3, Imm32(sizeof(RectifierFrameLayout)), r3);
-
-    {
-        Label notConstructing;
-
-        masm.branchTest32(Assembler::Zero, r1, Imm32(CalleeToken_FunctionConstructing),
-                          &notConstructing);
+    masm.moveValue(UndefinedValue(), r5, r4);
 
-        // Add sizeof(Value) to overcome |this|
-        masm.ma_dataTransferN(IsLoad, 64, true, r3, Imm32(8), r4, Offset);
-        masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex);
-
-        // Include the newly pushed newTarget value in the frame size
-        // calculated below.
-        masm.add32(Imm32(1), r6);
-
-        masm.bind(&notConstructing);
-    }
+    masm.ma_mov(sp, r3); // Save %sp.
+    masm.ma_mov(sp, r7); // Save %sp again.
 
     // Push undefined.
-    masm.moveValue(UndefinedValue(), r5, r4);
     {
         Label undefLoopTop;
         masm.bind(&undefLoopTop);
         masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex);
         masm.ma_sub(r2, Imm32(1), r2, SetCC);
 
         masm.ma_b(&undefLoopTop, Assembler::NonZero);
     }
 
+    // Get the topmost argument.
+
+    masm.ma_alu(r3, lsl(r8, 3), r3, OpAdd); // r3 <- r3 + nargs * 8
+    masm.ma_add(r3, Imm32(sizeof(RectifierFrameLayout)), r3);
+
     // Push arguments, |nargs| + 1 times (to include |this|).
     {
         Label copyLoopTop;
         masm.bind(&copyLoopTop);
         masm.ma_dataTransferN(IsLoad, 64, true, r3, Imm32(-8), r4, PostIndex);
         masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex);
 
         masm.ma_sub(r8, Imm32(1), r8, SetCC);
--- a/js/src/jit/x64/Trampoline-x64.cpp
+++ b/js/src/jit/x64/Trampoline-x64.cpp
@@ -82,28 +82,16 @@ JitRuntime::generateEnterJIT(JSContext* 
     // Save arguments passed in registers needed after function call.
     masm.push(result);
 
     // Remember stack depth without padding and arguments.
     masm.mov(rsp, r14);
 
     // Remember number of bytes occupied by argument vector
     masm.mov(reg_argc, r13);
-
-    // if we are constructing, that also needs to include newTarget
-    {
-        Label noNewTarget;
-        masm.branchTest32(Assembler::Zero, token, Imm32(CalleeToken_FunctionConstructing),
-                          &noNewTarget);
-
-        masm.addq(Imm32(1), r13);
-
-        masm.bind(&noNewTarget);
-    }
-
     masm.shll(Imm32(3), r13);   // r13 = argc * sizeof(Value)
     static_assert(sizeof(Value) == 1 << 3, "Constant is baked in assembly code");
 
     // Guarantee stack alignment of Jit frames.
     //
     // This code compensates for the offset created by the copy of the vector of
     // arguments, such that the jit frame will be aligned once the return
     // address is pushed on the stack.
@@ -118,17 +106,17 @@ JitRuntime::generateEnterJIT(JSContext* 
     masm.andl(Imm32(JitStackAlignment - 1), r12);
     masm.subq(r12, rsp);
 
     /***************************************************************
     Loop over argv vector, push arguments onto stack in reverse order
     ***************************************************************/
 
     // r13 still stores the number of bytes in the argument vector.
-    masm.addq(reg_argv, r13); // r13 points above last argument or newTarget
+    masm.addq(reg_argv, r13); // r13 points above last argument.
 
     // while r13 > rdx, push arguments.
     {
         Label header, footer;
         masm.bind(&header);
 
         masm.cmpPtr(r13, reg_argv);
         masm.j(AssemblerX86Shared::BelowOrEqual, &footer);
@@ -404,37 +392,26 @@ JitRuntime::generateArgumentsRectifier(J
     masm.addl(Imm32(1), r8);
 
     // Load |nformals| into %rcx.
     masm.loadPtr(Address(rsp, RectifierFrameLayout::offsetOfCalleeToken()), rax);
     masm.mov(rax, rcx);
     masm.andq(Imm32(uint32_t(CalleeTokenMask)), rcx);
     masm.movzwl(Operand(rcx, JSFunction::offsetOfNargs()), rcx);
 
-    // Stash another copy in r11, since we are going to do destructive operations
-    // on rcx
-    masm.mov(rcx, r11);
-
-    static_assert(CalleeToken_FunctionConstructing == 1,
-      "Ensure that we can use the constructing bit to count the value");
-    masm.mov(rax, rdx);
-    masm.andq(Imm32(uint32_t(CalleeToken_FunctionConstructing)), rdx);
-
-    // Including |this|, and |new.target|, there are (|nformals| + 1 + isConstructing)
-    // arguments to push to the stack.  Then we push a JitFrameLayout.  We
-    // compute the padding expressed in the number of extra |undefined| values
-    // to push on the stack.
+    // Including |this|, there are (|nformals| + 1) arguments to push to the
+    // stack.  Then we push a JitFrameLayout.  We compute the padding expressed
+    // in the number of extra |undefined| values to push on the stack.
     static_assert(sizeof(JitFrameLayout) % JitStackAlignment == 0,
       "No need to consider the JitFrameLayout for aligning the stack");
     static_assert(JitStackAlignment % sizeof(Value) == 0,
       "Ensure that we can pad the stack by pushing extra UndefinedValue");
 
     MOZ_ASSERT(IsPowerOfTwo(JitStackValueAlignment));
     masm.addl(Imm32(JitStackValueAlignment - 1 /* for padding */ + 1 /* for |this| */), rcx);
-    masm.addl(rdx, rcx);
     masm.andl(Imm32(~(JitStackValueAlignment - 1)), rcx);
 
     // Load the number of |undefined|s to push into %rcx.
     masm.subq(r8, rcx);
 
     // Caller:
     // [arg2] [arg1] [this] [[argc] [callee] [descr] [raddr]] <- rsp <- r9
     // '------ #r8 -------'
@@ -474,38 +451,16 @@ JitRuntime::generateArgumentsRectifier(J
 
         masm.bind(&copyLoopTop);
         masm.push(Operand(rcx, 0x0));
         masm.subq(Imm32(sizeof(Value)), rcx);
         masm.subl(Imm32(1), r8);
         masm.j(Assembler::NonZero, &copyLoopTop);
     }
 
-    // if constructing, copy newTarget
-    {
-        Label notConstructing;
-
-        masm.branchTest32(Assembler::Zero, rax, Imm32(CalleeToken_FunctionConstructing),
-                          &notConstructing);
-
-        // thisFrame[numFormals] = prevFrame[argc]
-        ValueOperand newTarget(r10);
-
-        // +1 for |this|. We want vp[argc], so don't subtract 1
-        BaseIndex newTargetSrc(r9, rdx, TimesEight, sizeof(RectifierFrameLayout) + sizeof(Value));
-        masm.loadValue(newTargetSrc, newTarget);
-
-        // Again, 1 for |this|
-        BaseIndex newTargetDest(rsp, r11, TimesEight, sizeof(Value));
-        masm.storeValue(newTarget, newTargetDest);
-
-        masm.bind(&notConstructing);
-    }
-
-
     // Caller:
     // [arg2] [arg1] [this] [[argc] [callee] [descr] [raddr]] <- r9
     //
     //
     // Rectifier frame:
     // [undef] [undef] [undef] [arg2] [arg1] [this] <- rsp [[argc] [callee] [descr] [raddr]]
     //
 
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -60,32 +60,18 @@ JitRuntime::generateEnterJIT(JSContext* 
     masm.push(ebx);
     masm.push(esi);
     masm.push(edi);
 
     // Keep track of the stack which has to be unwound after returning from the
     // compiled function.
     masm.movl(esp, esi);
 
-    // Load the number of values to be copied (argc) into eax
+    // eax <- 8*argc, eax is now the offset betwen argv and the last
     masm.loadPtr(Address(ebp, ARG_ARGC), eax);
-
-    // If we are constructing, that also needs to include newTarget
-    {
-        Label noNewTarget;
-        masm.loadPtr(Address(ebp, ARG_CALLEETOKEN), edx);
-        masm.branchTest32(Assembler::Zero, edx, Imm32(CalleeToken_FunctionConstructing),
-                          &noNewTarget);
-
-        masm.addl(Imm32(1), eax);
-
-        masm.bind(&noNewTarget);
-    }
-
-    // eax <- 8*numValues, eax is now the offset betwen argv and the last value.
     masm.shll(Imm32(3), eax);
 
     // Guarantee stack alignment of Jit frames.
     //
     // This code compensates for the offset created by the copy of the vector of
     // arguments, such that the jit frame will be aligned once the return
     // address is pushed on the stack.
     //
@@ -406,24 +392,16 @@ JitRuntime::generateArgumentsRectifier(J
       "No need to consider the JitFrameLayout for aligning the stack");
     static_assert((sizeof(Value) + 2 * sizeof(void*)) % JitStackAlignment == 0,
       "No need to consider |this| and the frame pointer and its padding for aligning the stack");
     static_assert(JitStackAlignment % sizeof(Value) == 0,
       "Ensure that we can pad the stack by pushing extra UndefinedValue");
 
     MOZ_ASSERT(IsPowerOfTwo(JitStackValueAlignment));
     masm.addl(Imm32(JitStackValueAlignment - 1 /* for padding */), ecx);
-
-    // Account for newTarget, if necessary.
-    static_assert(CalleeToken_FunctionConstructing == 1,
-      "Ensure that we can use the constructing bit to count an extra push");
-    masm.mov(eax, edx);
-    masm.andl(Imm32(CalleeToken_FunctionConstructing), edx);
-    masm.addl(edx, ecx);
-
     masm.andl(Imm32(~(JitStackValueAlignment - 1)), ecx);
     masm.subl(esi, ecx);
 
     // Copy the number of actual arguments.
     masm.loadPtr(Address(esp, RectifierFrameLayout::offsetOfNumActualArgs()), edx);
 
     masm.moveValue(UndefinedValue(), ebx, edi);
 
@@ -470,41 +448,16 @@ JitRuntime::generateArgumentsRectifier(J
         masm.bind(&copyLoopTop);
         masm.push(Operand(ecx, sizeof(Value)/2));
         masm.push(Operand(ecx, 0x0));
         masm.subl(Imm32(sizeof(Value)), ecx);
         masm.subl(Imm32(1), esi);
         masm.j(Assembler::NonZero, &copyLoopTop);
     }
 
-    {
-        Label notConstructing;
-
-        masm.mov(eax, ebx);
-        masm.branchTest32(Assembler::Zero, ebx, Imm32(CalleeToken_FunctionConstructing),
-                          &notConstructing);
-
-        BaseValueIndex src(FramePointer, edx,
-                           sizeof(RectifierFrameLayout) +
-                           sizeof(Value) +
-                           sizeof(void*));
-
-        masm.andl(Imm32(CalleeTokenMask), ebx);
-        masm.movzwl(Operand(ebx, JSFunction::offsetOfNargs()), ebx);
-
-        BaseValueIndex dst(esp, ebx, sizeof(Value));
-
-        ValueOperand newTarget(ecx, edi);
-
-        masm.loadValue(src, newTarget);
-        masm.storeValue(newTarget, dst);
-
-        masm.bind(&notConstructing);
-    }
-
     // Construct descriptor, accounting for pushed frame pointer above
     masm.lea(Operand(FramePointer, sizeof(void*)), ebx);
     masm.subl(esp, ebx);
     masm.makeFrameDescriptor(ebx, JitFrame_Rectifier);
 
     // Construct JitFrameLayout.
     masm.push(edx); // number of actual arguments
     masm.push(eax); // callee token
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -334,17 +334,16 @@ MSG_DEF(JSMSG_USELESS_EXPR,            0
 MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL,  0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body")
 MSG_DEF(JSMSG_VAR_HIDES_ARG,           1, JSEXN_TYPEERR, "variable {0} redeclares argument")
 MSG_DEF(JSMSG_WHILE_AFTER_DO,          0, JSEXN_SYNTAXERR, "missing while after do-loop body")
 MSG_DEF(JSMSG_YIELD_IN_ARROW,          0, JSEXN_SYNTAXERR, "arrow function may not contain yield")
 MSG_DEF(JSMSG_YIELD_IN_DEFAULT,        0, JSEXN_SYNTAXERR, "yield in default expression")
 MSG_DEF(JSMSG_BAD_COLUMN_NUMBER,       0, JSEXN_RANGEERR, "column number out of range")
 MSG_DEF(JSMSG_COMPUTED_NAME_IN_PATTERN,0, JSEXN_SYNTAXERR, "computed property names aren't supported in this destructuring declaration")
 MSG_DEF(JSMSG_DEFAULT_IN_PATTERN,      0, JSEXN_SYNTAXERR, "destructuring defaults aren't supported in this destructuring declaration")
-MSG_DEF(JSMSG_BAD_NEWTARGET,           0, JSEXN_SYNTAXERR, "new.target only allowed in non-exotic functions")
 
 // asm.js
 MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL,       1, JSEXN_TYPEERR, "asm.js type error: {0}")
 MSG_DEF(JSMSG_USE_ASM_LINK_FAIL,       1, JSEXN_TYPEERR, "asm.js link error: {0}")
 MSG_DEF(JSMSG_USE_ASM_TYPE_OK,         1, JSEXN_NONE,    "Successfully compiled asm.js code ({0})")
 
 // Proxy
 MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE,   2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value")
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -50,17 +50,16 @@ UNIFIED_SOURCES += [
     'testIntTypesABI.cpp',
     'testIsInsideNursery.cpp',
     'testJSEvaluateScript.cpp',
     'testLookup.cpp',
     'testLooselyEqual.cpp',
     'testMappedArrayBuffer.cpp',
     'testMutedErrors.cpp',
     'testNewObject.cpp',
-    'testNewTargetInvokeConstructor.cpp',
     'testNullRoot.cpp',
     'testObjectEmulatingUndefined.cpp',
     'testOOM.cpp',
     'testOps.cpp',
     'testParseJSON.cpp',
     'testPersistentRooted.cpp',
     'testPreserveJitCode.cpp',
     'testProfileStrings.cpp',
deleted file mode 100644
--- a/js/src/jsapi-tests/testNewTargetInvokeConstructor.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "jsapi.h"
-
-#include "jsapi-tests/tests.h"
-
-BEGIN_TEST(testNewTargetInvokeConstructor)
-{
-    JS::RootedValue func(cx);
-
-    EVAL("(function(expected) { if (expected !== new.target) throw new Error('whoops'); })",
-         &func);
-
-    JS::AutoValueArray<1> args(cx);
-    args[0].set(func);
-
-    JS::RootedValue rval(cx);
-
-    CHECK(JS::Construct(cx, func, args, &rval));
-
-    return true;
-}
-END_TEST(testNewTargetInvokeConstructor)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4408,38 +4408,37 @@ JS_PUBLIC_API(bool)
 JS::Construct(JSContext* cx, HandleValue fval, const JS::HandleValueArray& args,
               MutableHandleValue rval)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, fval, args);
     AutoLastFrameCheck lfc(cx);
 
-    return InvokeConstructor(cx, fval, args.length(), args.begin(), false, rval);
+    return InvokeConstructor(cx, fval, args.length(), args.begin(), rval);
 }
 
 static JSObject*
 JS_NewHelper(JSContext* cx, HandleObject ctor, const JS::HandleValueArray& inputArgs)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, ctor, inputArgs);
 
     // This is not a simple variation of JS_CallFunctionValue because JSOP_NEW
     // is not a simple variation of JSOP_CALL. We have to determine what class
     // of object to create, create it, and clamp the return value to an object,
     // among other details. InvokeConstructor does the hard work.
     InvokeArgs args(cx);
-    if (!args.init(inputArgs.length(), true))
+    if (!args.init(inputArgs.length()))
         return nullptr;
 
     args.setCallee(ObjectValue(*ctor));
     args.setThis(NullValue());
     PodCopy(args.array(), inputArgs.begin(), inputArgs.length());
-    args.newTarget().setObject(*ctor);
 
     if (!InvokeConstructor(cx, args))
         return nullptr;
 
     if (!args.rval().isObject()) {
         /*
          * Although constructors may return primitives (via proxies), this
          * API is asking for an object, so we report an error.
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3186,17 +3186,17 @@ array_of(JSContext* cx, unsigned argc, V
         return ArrayFromCallArgs(cx, group, args);
     }
 
     // Step 4.
     RootedObject obj(cx);
     {
         RootedValue v(cx);
         Value argv[1] = {NumberValue(args.length())};
-        if (!InvokeConstructor(cx, args.thisv(), 1, argv, false, &v))
+        if (!InvokeConstructor(cx, args.thisv(), 1, argv, &v))
             return false;
         obj = ToObject(cx, v);
         if (!obj)
             return false;
     }
 
     // Step 8.
     for (unsigned k = 0; k < args.length(); k++) {
@@ -3281,20 +3281,16 @@ static const JSFunctionSpec array_static
     JS_FS_END
 };
 
 /* ES5 15.4.2 */
 bool
 js::ArrayConstructor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    
-    if (args.isConstructing())
-        MOZ_ASSERT(args.newTarget().toObject().as<JSFunction>().native() == js::ArrayConstructor);
-    
     RootedObjectGroup group(cx, ObjectGroup::callingAllocationSiteGroup(cx, JSProto_Array));
     if (!group)
         return false;
 
     if (args.length() != 1 || !args[0].isNumber())
         return ArrayFromCallArgs(cx, group, args);
 
     uint32_t length;
--- a/js/src/jsast.tbl
+++ b/js/src/jsast.tbl
@@ -33,17 +33,16 @@ ASTDEF(AST_ARROW_EXPR,            "Arrow
 ASTDEF(AST_ARRAY_EXPR,            "ArrayExpression",                "arrayExpression")
 ASTDEF(AST_SPREAD_EXPR,           "SpreadExpression",               "spreadExpression")
 ASTDEF(AST_OBJECT_EXPR,           "ObjectExpression",               "objectExpression")
 ASTDEF(AST_THIS_EXPR,             "ThisExpression",                 "thisExpression")
 ASTDEF(AST_COMP_EXPR,             "ComprehensionExpression",        "comprehensionExpression")
 ASTDEF(AST_GENERATOR_EXPR,        "GeneratorExpression",            "generatorExpression")
 ASTDEF(AST_YIELD_EXPR,            "YieldExpression",                "yieldExpression")
 ASTDEF(AST_CLASS_EXPR,            "ClassExpression",                "classExpression")
-ASTDEF(AST_NEWTARGET_EXPR,        "NewTargetExpression",            "newTargetExpression")
 
 ASTDEF(AST_EMPTY_STMT,            "EmptyStatement",                 "emptyStatement")
 ASTDEF(AST_BLOCK_STMT,            "BlockStatement",                 "blockStatement")
 ASTDEF(AST_EXPR_STMT,             "ExpressionStatement",            "expressionStatement")
 ASTDEF(AST_LAB_STMT,              "LabeledStatement",               "labeledStatement")
 ASTDEF(AST_IF_STMT,               "IfStatement",                    "ifStatement")
 ASTDEF(AST_SWITCH_STMT,           "SwitchStatement",                "switchStatement")
 ASTDEF(AST_WHILE_STMT,            "WhileStatement",                 "whileStatement")
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1547,39 +1547,31 @@ js::CallOrConstructBoundFunction(JSConte
 
     /* 15.3.4.5.1 step 3, 15.3.4.5.2 step 1. */
     RootedObject target(cx, fun->getBoundFunctionTarget());
 
     /* 15.3.4.5.1 step 2. */
     const Value& boundThis = fun->getBoundFunctionThis();
 
     InvokeArgs invokeArgs(cx);
-    if (!invokeArgs.init(args.length() + argslen, args.isConstructing()))
+    if (!invokeArgs.init(args.length() + argslen))
         return false;
 
     /* 15.3.4.5.1, 15.3.4.5.2 step 4. */
     for (unsigned i = 0; i < argslen; i++)
         invokeArgs[i].set(fun->getBoundFunctionArgument(i));
     PodCopy(invokeArgs.array() + argslen, vp + 2, args.length());
 
     /* 15.3.4.5.1, 15.3.4.5.2 step 5. */
     invokeArgs.setCallee(ObjectValue(*target));
 
     bool constructing = args.isConstructing();
     if (!constructing)
         invokeArgs.setThis(boundThis);
 
-    /* ES6 9.4.1.2 step 5 */
-    if (constructing) {
-        if (&args.newTarget().toObject() == fun)
-            invokeArgs.newTarget().setObject(*target);
-        else
-            invokeArgs.newTarget().set(args.newTarget());
-    }
-
     if (constructing ? !InvokeConstructor(cx, invokeArgs) : !Invoke(cx, invokeArgs))
         return false;
 
     args.rval().set(invokeArgs.rval());
     return true;
 }
 
 static bool
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -604,30 +604,26 @@ fun_bind(JSContext* cx, unsigned argc, V
  */
 class FunctionExtended : public JSFunction
 {
   public:
     static const unsigned NUM_EXTENDED_SLOTS = 2;
 
     /* Arrow functions store their lexical |this| in the first extended slot. */
     static const unsigned ARROW_THIS_SLOT = 0;
-    static const unsigned ARROW_NEWTARGET_SLOT = 1;
 
     static const unsigned METHOD_HOMEOBJECT_SLOT = 0;
 
     static inline size_t offsetOfExtendedSlot(unsigned which) {
         MOZ_ASSERT(which < NUM_EXTENDED_SLOTS);
         return offsetof(FunctionExtended, extendedSlots) + which * sizeof(HeapValue);
     }
     static inline size_t offsetOfArrowThisSlot() {
         return offsetOfExtendedSlot(ARROW_THIS_SLOT);
     }
-    static inline size_t offsetOfArrowNewTargetSlot() {
-        return offsetOfExtendedSlot(ARROW_NEWTARGET_SLOT);
-    }
 
   private:
     friend class JSFunction;
 
     /* Reserved slots available for storage by particular native functions. */
     HeapValue extendedSlots[NUM_EXTENDED_SLOTS];
 };
 
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -443,24 +443,26 @@ GetCustomIterator(JSContext* cx, HandleO
     if (!cx->runningWithTrustedPrincipals())
         ++sCustomIteratorCount;
 
     /* Otherwise call it and return that object. */
     Value arg = BooleanValue((flags & JSITER_FOREACH) == 0);
     if (!Invoke(cx, ObjectValue(*obj), rval, 1, &arg, &rval))
         return false;
     if (rval.isPrimitive()) {
-        // Ignore the stack when throwing. We can't tell whether we were
-        // supposed to skip over a new.target or not.
+        /*
+         * We are always coming from js::ValueToIterator, and we are no longer on
+         * trace, so the object we are iterating over is on top of the stack (-1).
+         */
         JSAutoByteString bytes;
         if (!AtomToPrintableString(cx, name, &bytes))
             return false;
         RootedValue val(cx, ObjectValue(*obj));
         ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
-                          JSDVG_IGNORE_STACK, val, nullptr, bytes.ptr());
+                          -1, val, nullptr, bytes.ptr());
         return false;
     }
     objp.set(&rval.toObject());
     return true;
 }
 
 template <typename T>
 static inline bool
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -114,21 +114,19 @@ js::StackUses(JSScript* script, jsbyteco
     const JSCodeSpec& cs = js_CodeSpec[op];
     if (cs.nuses >= 0)
         return cs.nuses;
 
     MOZ_ASSERT(js_CodeSpec[op].nuses == -1);
     switch (op) {
       case JSOP_POPN:
         return GET_UINT16(pc);
-      case JSOP_NEW:
-        return 2 + GET_ARGC(pc) + 1;
       default:
         /* stack: fun, this, [argc arguments] */
-        MOZ_ASSERT(op == JSOP_CALL || op == JSOP_EVAL ||
+        MOZ_ASSERT(op == JSOP_NEW || op == JSOP_CALL || op == JSOP_EVAL ||
                    op == JSOP_STRICTEVAL || op == JSOP_FUNCALL || op == JSOP_FUNAPPLY);
         return 2 + GET_ARGC(pc);
     }
 }
 
 unsigned
 js::StackDefs(JSScript* script, jsbytecode* pc)
 {
@@ -1269,18 +1267,16 @@ ExpressionDecompiler::decompilePC(jsbyte
         break;
       }
       case JSOP_UNDEFINED:
         return write(js_undefined_str);
       case JSOP_THIS:
         // |this| could convert to a very long object initialiser, so cite it by
         // its keyword name.
         return write(js_this_str);
-      case JSOP_NEWTARGET:
-        return write("new.target");
       case JSOP_CALL:
       case JSOP_FUNCALL:
         return decompilePCForStackOperand(pc, -int32_t(GET_ARGC(pc) + 2)) &&
                write("(...)");
       case JSOP_SPREADCALL:
         return decompilePCForStackOperand(pc, -int32_t(3)) &&
                write("(...)");
       case JSOP_NEWARRAY:
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -677,18 +677,16 @@ class NodeBuilder
     bool comprehensionIf(HandleValue test, TokenPos* pos, MutableHandleValue dst);
 
     bool comprehensionExpression(HandleValue body, NodeVector& blocks, HandleValue filter,
                                  bool isLegacy, TokenPos* pos, MutableHandleValue dst);
 
     bool generatorExpression(HandleValue body, NodeVector& blocks, HandleValue filter,
                              bool isLegacy, TokenPos* pos, MutableHandleValue dst);
 
-    bool newTargetExpression(TokenPos* pos, MutableHandleValue dst);
-
     /*
      * declarations
      */
 
     bool variableDeclaration(NodeVector& elts, VarDeclKind kind, TokenPos* pos,
                              MutableHandleValue dst);
 
     /*
@@ -1746,26 +1744,16 @@ NodeBuilder::classDefinition(bool expr, 
 
     return newNode(type, pos,
                    "name", name,
                    "heritage", heritage,
                    "body", block,
                    dst);
 }
 
-bool
-NodeBuilder::newTargetExpression(TokenPos* pos, MutableHandleValue dst)
-{
-    RootedValue cb(cx, callbacks[AST_NEWTARGET_EXPR]);
-    if (!cb.isNull())
-        return callback(cb, pos, dst);
-
-    return newNode(AST_NEWTARGET_EXPR, pos, dst);
-}
-
 namespace {
 
 /*
  * Serialization of parse nodes to JavaScript objects.
  *
  * All serialization methods take a non-nullable ParseNode pointer.
  */
 class ASTSerializer
@@ -3174,19 +3162,16 @@ ASTSerializer::expression(ParseNode* pn,
 
         /* NB: it's no longer the case that pn_count could be 2. */
         LOCAL_ASSERT(pn->pn_count == 1);
         return comprehension(pn->pn_head, dst);
 
       case PNK_CLASS:
         return classDefinition(pn, true, dst);
 
-      case PNK_NEWTARGET:
-        return builder.newTargetExpression(&pn->pn_pos, dst);
-
       default:
         LOCAL_NOT_REACHED("unexpected expression type");
     }
 }
 
 bool
 ASTSerializer::propertyName(ParseNode* pn, MutableHandleValue dst)
 {
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -299,18 +299,16 @@ CrossCompartmentWrapper::construct(JSCon
     RootedObject wrapped(cx, wrappedObject(wrapper));
     {
         AutoCompartment call(cx, wrapped);
 
         for (size_t n = 0; n < args.length(); ++n) {
             if (!cx->compartment()->wrap(cx, args[n]))
                 return false;
         }
-        if (!cx->compartment()->wrap(cx, args.newTarget()))
-            return false;
         if (!Wrapper::construct(cx, wrapper, args))
             return false;
     }
     return cx->compartment()->wrap(cx, args.rval());
 }
 
 bool
 CrossCompartmentWrapper::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
--- a/js/src/proxy/DirectProxyHandler.cpp
+++ b/js/src/proxy/DirectProxyHandler.cpp
@@ -77,17 +77,17 @@ DirectProxyHandler::call(JSContext* cx, 
     return Invoke(cx, args.thisv(), target, args.length(), args.array(), args.rval());
 }
 
 bool
 DirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const
 {
     assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
     RootedValue target(cx, proxy->as<ProxyObject>().private_());
-    return InvokeConstructor(cx, target, args.length(), args.array(), true, args.rval());
+    return InvokeConstructor(cx, target, args.length(), args.array(), args.rval());
 }
 
 bool
 DirectProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
                                CallArgs args) const
 {
     args.setThis(ObjectValue(*args.thisv().toObject().as<ProxyObject>().target()));
     if (!test(args.thisv())) {
--- a/js/src/proxy/ScriptedDirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp
@@ -1033,24 +1033,23 @@ ScriptedDirectProxyHandler::construct(JS
     // step 4-5
     RootedValue trap(cx);
     if (!GetProperty(cx, handler, handler, cx->names().construct, &trap))
         return false;
 
     // step 6
     if (trap.isUndefined()) {
         RootedValue targetv(cx, ObjectValue(*target));
-        return InvokeConstructor(cx, targetv, args.length(), args.array(), true, args.rval());
+        return InvokeConstructor(cx, targetv, args.length(), args.array(), args.rval());
     }
 
     // step 8-9
     Value constructArgv[] = {
         ObjectValue(*target),
-        ObjectValue(*argsArray),
-        args.newTarget()
+        ObjectValue(*argsArray)
     };
     RootedValue thisValue(cx, ObjectValue(*handler));
     if (!Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv, args.rval()))
         return false;
 
     // step 10
     if (!args.rval().isObject()) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT);
--- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp
@@ -462,17 +462,17 @@ CallableScriptedIndirectProxyHandler::ca
 bool
 CallableScriptedIndirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const
 {
     assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
     RootedObject ccHolder(cx, &proxy->as<ProxyObject>().extra(0).toObject());
     MOZ_ASSERT(ccHolder->getClass() == &CallConstructHolder);
     RootedValue construct(cx, ccHolder->as<NativeObject>().getReservedSlot(1));
     MOZ_ASSERT(construct.isObject() && construct.toObject().isCallable());
-    return InvokeConstructor(cx, construct, args.length(), args.array(), true, args.rval());
+    return InvokeConstructor(cx, construct, args.length(), args.array(), args.rval());
 }
 
 const CallableScriptedIndirectProxyHandler CallableScriptedIndirectProxyHandler::singleton;
 
 bool
 js::proxy_create(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetArgumentsIntact.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Since we put new.target at the end of the arguments vector, ensrue that it
-// doesn't interact with the arguments object
-
-var argsContent;
-
-function argsWithNewTarget(foo) {
-    assertEq(arguments.length, argsContent.length);
-    for (let i = 0; i < arguments.length; i++)
-        assertEq(arguments[i], argsContent[i]);
-    let nt = new.target;
-
-    // Assigning to the arguments object shouldn't infect new.target, either
-    arguments[arguments.length] = 42;
-    assertEq(new.target, nt);
-}
-
-// Test constructing invocations, with under and overflow
-argsContent = [];
-for (let i = 0; i < 100; i++)
-    new argsWithNewTarget();
-
-argsContent = [1];
-for (let i = 0; i < 100; i++)
-    new argsWithNewTarget(1);
-
-argsContent = [1,2,3];
-for (let i = 0; i < 100; i++)
-    new argsWithNewTarget(1, 2, 3);
-
-// Test spreadnew as well.
-argsContent = [];
-for (let i = 0; i < 100; i++)
-    new argsWithNewTarget(...[]);
-
-argsContent = [1];
-for (let i = 0; i < 100; i++)
-    new argsWithNewTarget(...[1]);
-
-argsContent = [1,2,3];
-for (let i = 0; i < 100; i++)
-    new argsWithNewTarget(...[1,2,3]);
-
-if (typeof reportCompare === "function")
-    reportCompare(0,0,"OK");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetArrow.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// new.target is valid in any arrow function not in a global context.
-new Function('(() => new.target)()');
-
-// It's also good inside eval, but not global eval
-assertThrowsInstanceOf(() => eval('() => new.target'), SyntaxError);
-
-function assertNewTarget(expected) {
-    assertEq((()=>new.target)(), expected);
-    assertEq(eval('()=>new.target')(), expected);
-
-    // Make sure that arrow functions can escape their original context and
-    // still get the right answer.
-    return (() => new.target);
-}
-
-const ITERATIONS = 550;
-for (let i = 0; i < ITERATIONS; i++)
-    assertEq(assertNewTarget(undefined)(), undefined);
-
-for (let i = 0; i < ITERATIONS; i++)
-    assertEq(new assertNewTarget(assertNewTarget)(), assertNewTarget);
-
-if (typeof reportCompare === 'function')
-    reportCompare(0,0,"OK");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetBound.js
+++ /dev/null
@@ -1,16 +0,0 @@
-function boundTarget(expected) {
-    assertEq(new.target, expected);
-}
-
-let bound = boundTarget.bind(undefined);
-
-const TEST_ITERATIONS = 550;
-
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    bound(undefined);
-
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    new bound(boundTarget);
-
-if (typeof reportCompare === "function")
-    reportCompare(0,0,"OK");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetCCW.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Make sure we wrap the new target on CCW construct calls.
-var g = newGlobal();
-
-let f = g.eval('(function (expected) { this.accept = new.target === expected; })');
-
-for (let i = 0; i < 1100; i++)
-    assertEq(new f(f).accept, true);
-
-if (typeof reportCompare === 'function')
-    reportCompare(0,0,"OK");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetDVG.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function thunk() {
-    new.target();
-}
-assertThrownErrorContains(thunk, "new.target");
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0, "OK");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetDirectInvoke.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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);
-
-for (let i = 0; i < 100; i++)
-    assertNewTarget(undefined);
-
-for (let i = 0; i < 100; i++)
-    assertNewTarget(undefined, null, 1);
-
-// Test spread-call
-for (let i = 0; i < 100; i++)
-    assertNewTarget(...[undefined]);
-
-for (let i = 0; i < 100; i++)
-    assertNewTarget(...[undefined, null]);
-
-for (let i = 0; i < 100; i++)
-    assertNewTarget(...[undefined, null, 1]);
-
-// Test constructing invocations, again with under and overflow
-for (let i = 0; i < 100; i++)
-    new assertNewTarget(assertNewTarget, null);
-
-for (let i = 0; i < 100; i++)
-    new assertNewTarget(assertNewTarget);
-
-for (let i = 0; i < 100; i++)
-    new assertNewTarget(assertNewTarget, null, 1);
-
-// Test spreadnew as well.
-for (let i = 0; i < 100; i++)
-    new assertNewTarget(...[assertNewTarget]);
-
-for (let i = 0; i < 100; i++)
-    new assertNewTarget(...[assertNewTarget, null]);
-
-for (let i = 0; i < 100; i++)
-    new assertNewTarget(...[assertNewTarget, null, 1]);
-
-if (typeof reportCompare === "function")
-    reportCompare(0,0,"OK");
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 invalid inside eval inside top-level 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);
-    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");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetGenerators.js
+++ /dev/null
@@ -1,24 +0,0 @@
-function *generatorNewTarget(expected) {
-    assertEq(new.target, expected);
-    assertEq(eval('new.target'), expected);
-    assertEq((() => new.target)(), expected);
-    yield (() => new.target);
-}
-
-const ITERATIONS = 25;
-
-for (let i = 0; i < ITERATIONS; i++)
-    assertEq(generatorNewTarget(undefined).next().value(), undefined);
-
-for (let i = 0; i < ITERATIONS; i++)
-    assertEq(new generatorNewTarget(generatorNewTarget).next().value(),
-             generatorNewTarget);
-
-// also check to make sure it's useful in yield inside generators.
-// Plus, this code is so ugly, how could it not be a test? ;)
-// Thanks to anba for supplying this ludicrous expression.
-assertDeepEq([...new function*(i) { yield i; if(i > 0) yield* new new.target(i-1) }(10)],
-             [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]);
-
-if (typeof reportCompare === 'function')
-    reportCompare(0,0,"OK");
deleted file mode 100644
--- a/js/src/tests/ecma_6/Class/newTargetMethods.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Just like newTargetDirectInvoke, except to prove it works in functions
-// defined with method syntax as well. Note that methods, getters, and setters
-// are not constructible.
-
-let ol = {
-    olTest(arg) { assertEq(arg, 4); assertEq(new.target, undefined); },
-    get ol() { assertEq(new.target, undefined); },
-    set ol(arg) { assertEq(arg, 4); assertEq(new.target, undefined); }
-}
-
-class cl {
-    constructor() { assertEq(new.target, cl); }
-    clTest(arg) { assertEq(arg, 4); assertEq(new.target, undefined); }
-    get cl() { assertEq(new.target, undefined); }
-    set cl(arg) { assertEq(arg, 4); assertEq(new.target, undefined); }
-
-    static staticclTest(arg) { assertEq(arg, 4); assertEq(new.target, undefined); }
-    static get staticcl() { assertEq(new.target, undefined); }
-    static set staticcl(arg) { assertEq(arg, 4); assertEq(new.target, undefined); }
-}
-
-const TEST_ITERATIONS = 150;
-
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    ol.olTest(4);
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    ol.ol;
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    ol.ol = 4;
-
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    cl.staticclTest(4);
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    cl.staticcl;
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    cl.staticcl = 4;
-
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    new cl();
-
-let clInst = new cl();
-
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    clInst.clTest(4);
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    clInst.cl;
-for (let i = 0; i < TEST_ITERATIONS; i++)
-    clInst.cl = 4;
-
-
-if (typeof reportCompare === "function")
-    reportCompare(0,0,"OK");
--- a/js/src/tests/ecma_6/Class/shell.js
+++ b/js/src/tests/ecma_6/Class/shell.js
@@ -7,19 +7,8 @@ if (typeof version != 'undefined')
 function classesEnabled() {
     try {
         new Function("class Foo { constructor() { } }");
         return true;
     } catch (e if e instanceof SyntaxError) {
         return false;
     }
 }
-
-function assertThrownErrorContains(thunk, substr) {
-    try {
-        thunk();
-    } catch (e) {
-        if (e.message.indexOf(substr) !== -1)
-            return;
-        throw new Error("Expected error containing " + substr + ", got " + e);
-    }
-    throw new Error("Expected error containing " + substr + ", no exception thrown");
-}
--- a/js/src/tests/ecma_6/Class/superPropDVG.js
+++ b/js/src/tests/ecma_6/Class/superPropDVG.js
@@ -1,12 +1,23 @@
 // Super property accesses should play nice with the pretty printer.
 
 var test = `
 
+function assertThrownErrorContains(thunk, substr) {
+    try {
+        thunk();
+        throw new Error("Expected error containing " + substr + ", no exception thrown");
+    } catch (e) {
+        if (e.message.indexOf(substr) !== -1)
+            return;
+        throw new Error("Expected error containing " + substr + ", got " + e);
+    }
+}
+
 class testNonExistent {
     constructor() {
         super["prop"]();
     }
 }
 assertThrownErrorContains(() => new testNonExistent(), 'super["prop"]');
 
 var ol = { testNonExistent() { super.prop(); } };
--- a/js/src/tests/js1_7/extensions/regress-354945-01.js
+++ b/js/src/tests/js1_7/extensions/regress-354945-01.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 354945;
 var summary = 'Do not crash with new Iterator';
-var expect = 'TypeError: trap __iterator__ for ({__iterator__:(function (){ })}) returned a primitive value';
+var expect = 'TypeError: trap __iterator__ for obj returned a primitive value';
 var actual;
 
 
 //-----------------------------------------------------------------------------
 test();
 //-----------------------------------------------------------------------------
 
 function test()
--- a/js/src/tests/js1_7/extensions/regress-354945-02.js
+++ b/js/src/tests/js1_7/extensions/regress-354945-02.js
@@ -15,17 +15,17 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
-  expect = 'TypeError: trap __iterator__ for ({__iterator__:(function (){ })}) returned a primitive value';
+  expect = 'TypeError: trap __iterator__ for obj returned a primitive value';
   var obj = {};
   obj.__iterator__ = function(){ };
   try
   {
     for(t in (obj)) { }
   }
   catch(ex)
   {
--- a/js/src/tests/js1_8_5/reflect-parse/PatternAsserts.js
+++ b/js/src/tests/js1_8_5/reflect-parse/PatternAsserts.js
@@ -61,21 +61,16 @@ function assertProg(src, patt) {
 }
 
 function assertStmt(src, patt) {
     assertLocalStmt(src, patt);
     assertGlobalStmt(src, patt);
     assertBlockStmt(src, patt);
 }
 
-function assertInFunctionExpr(src, patt) {
-    assertLocalExpr(src, patt);
-    assertBlockExpr(src, patt);
-}
-
 function assertExpr(src, patt) {
     assertLocalExpr(src, patt);
     assertGlobalExpr(src, patt);
     assertBlockExpr(src, patt);
 }
 
 function assertDecl(src, patt) {
     assertLocalDecl(src, patt);
--- a/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js
+++ b/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js
@@ -165,19 +165,16 @@ function genFunExpr(id, args, body) {
                      generator: true });
 }
 function arrowExpr(args, body) {
     return Pattern({ type: "ArrowFunctionExpression",
                      params: args,
                      body: body });
 }
 
-function newTarget() {
-    return Pattern({ type: "NewTargetExpression" });
-}
 function unExpr(op, arg) {
     return Pattern({ type: "UnaryExpression", operator: op, argument: arg });
 }
 function binExpr(op, left, right) {
     return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right });
 }
 function aExpr(op, left, right) {
     return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right });
deleted file mode 100644
--- a/js/src/tests/js1_8_5/reflect-parse/newTarget.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// |reftest| skip-if(!xulRuntime.shell)
-function testNewTarget() {
-
-    // new.target is currently valid inside any non-arrow, non-generator function
-    assertInFunctionExpr("new.target", newTarget());
-
-    // even with gratuitous whitespace.
-    assertInFunctionExpr(`new.
-                            target`, newTarget());
-
-    // invalid in top-level scripts
-    assertError("new.target", SyntaxError);
-
-    // valid in arrow functions inside functions
-    assertInFunctionExpr("()=>new.target", arrowExpr([], newTarget()));
-    assertError("(() => new.target))", SyntaxError);
-
-    // valid in generators, too!
-    assertStmt("function *foo() { new.target; }", genFunDecl(ident("foo"), [],
-               blockStmt([exprStmt(newTarget())])));
-
-    // new.target is a member expression. You should be able to call, invoke, or
-    // access properties of it.
-    assertInFunctionExpr("new.target.foo", dotExpr(newTarget(), ident("foo")));
-    assertInFunctionExpr("new.target[\"foo\"]", memExpr(newTarget(), literal("foo")));
-
-    assertInFunctionExpr("new.target()", callExpr(newTarget(), []));
-    assertInFunctionExpr("new new.target()", newExpr(newTarget(), []));
-
-    // assignment to newTarget is an error
-    assertError("new.target = 4", SyntaxError);
-
-    // only new.target is a valid production, no shorn names or other names
-    assertError("new.", SyntaxError);
-    assertError("new.foo", SyntaxError);
-    assertError("new.targe", SyntaxError);
-
-    // obj.new.target is still a member expression
-    assertExpr("obj.new.target", dotExpr(dotExpr(ident("obj"), ident("new")), ident("target")));
-}
-
-runtest(testNewTarget);
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -191,17 +191,16 @@
     macro(starDefaultStar, starDefaultStar, "*default*") \
     macro(startTimestamp, startTimestamp, "startTimestamp") \
     macro(static, static_, "static") \
     macro(sticky, sticky, "sticky") \
     macro(strings, strings, "strings") \
     macro(StructType, StructType, "StructType") \
     macro(style, style, "style") \
     macro(super, super, "super") \
-    macro(target, target, "target") \
     macro(test, test, "test") \
     macro(throw, throw_, "throw") \
     macro(timestamp, timestamp, "timestamp") \
     macro(timeZone, timeZone, "timeZone") \
     macro(toGMTString, toGMTString, "toGMTString") \
     macro(toISOString, toISOString, "toISOString") \
     macro(toJSON, toJSON, "toJSON") \
     macro(toLocaleString, toLocaleString, "toLocaleString") \
--- 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/GeneratorObject.cpp
+++ b/js/src/vm/GeneratorObject.cpp
@@ -44,17 +44,16 @@ GeneratorObject::create(JSContext* cx, A
         obj = NewNativeObjectWithGivenProto(cx, &LegacyGeneratorObject::class_, proto);
     }
     if (!obj)
         return nullptr;
 
     GeneratorObject* genObj = &obj->as<GeneratorObject>();
     genObj->setCallee(*frame.callee());
     genObj->setThisValue(frame.thisValue());
-    genObj->setNewTarget(frame.newTarget());
     genObj->setScopeChain(*frame.scopeChain());
     if (frame.script()->needsArgsObj())
         genObj->setArgsObj(frame.argsObj());
     genObj->clearExpressionStack();
 
     return obj;
 }
 
@@ -158,19 +157,18 @@ bool
 GeneratorObject::resume(JSContext* cx, InterpreterActivation& activation,
                         HandleObject obj, HandleValue arg, GeneratorObject::ResumeKind resumeKind)
 {
     Rooted<GeneratorObject*> genObj(cx, &obj->as<GeneratorObject>());
     MOZ_ASSERT(genObj->isSuspended());
 
     RootedFunction callee(cx, &genObj->callee());
     RootedValue thisv(cx, genObj->thisValue());
-    RootedValue newTarget(cx, genObj->newTarget());
     RootedObject scopeChain(cx, &genObj->scopeChain());
-    if (!activation.resumeGeneratorFrame(callee, thisv, newTarget, scopeChain))
+    if (!activation.resumeGeneratorFrame(callee, thisv, scopeChain))
         return false;
 
     if (genObj->hasArgsObj())
         activation.regs().fp()->initArgsObj(genObj->argsObj());
 
     if (genObj->hasExpressionStack()) {
         uint32_t len = genObj->expressionStack().length();
         MOZ_ASSERT(activation.regs().spForStackDepth(len));
--- a/js/src/vm/GeneratorObject.h
+++ b/js/src/vm/GeneratorObject.h
@@ -26,17 +26,16 @@ class GeneratorObject : public NativeObj
 
     enum {
         CALLEE_SLOT = 0,
         THIS_SLOT,
         SCOPE_CHAIN_SLOT,
         ARGS_OBJ_SLOT,
         EXPRESSION_STACK_SLOT,
         YIELD_INDEX_SLOT,
-        NEWTARGET_SLOT,
         RESERVED_SLOTS
     };
 
     enum ResumeKind { NEXT, THROW, CLOSE };
 
   private:
     static bool suspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame, jsbytecode* pc,
                         Value* vp, unsigned nvalues);
@@ -113,27 +112,16 @@ class GeneratorObject : public NativeObj
     }
     void setExpressionStack(ArrayObject& expressionStack) {
         setFixedSlot(EXPRESSION_STACK_SLOT, ObjectValue(expressionStack));
     }
     void clearExpressionStack() {
         setFixedSlot(EXPRESSION_STACK_SLOT, NullValue());
     }
 
-    bool isConstructing() const {
-        return getFixedSlot(NEWTARGET_SLOT).isObject();
-    }
-    const Value& newTarget() const {
-        return getFixedSlot(NEWTARGET_SLOT);
-    }
-    void setNewTarget(Value newTarget) {
-        setFixedSlot(NEWTARGET_SLOT, newTarget);
-    }
-
-
     // The yield index slot is abused for a few purposes.  It's undefined if
     // it hasn't been set yet (before the initial yield), and null if the
     // generator is closed. If the generator is running, the yield index is
     // YIELD_INDEX_RUNNING. If the generator is in that bizarre "closing"
     // state, the yield index is YIELD_INDEX_CLOSING.
     //
     // If the generator is suspended, it's the yield index (stored as
     // JSOP_INITIALYIELD/JSOP_YIELD operand) of the yield instruction that
@@ -179,17 +167,16 @@ class GeneratorObject : public NativeObj
     }
     void setClosed() {
         setFixedSlot(CALLEE_SLOT, NullValue());
         setFixedSlot(THIS_SLOT, NullValue());
         setFixedSlot(SCOPE_CHAIN_SLOT, NullValue());
         setFixedSlot(ARGS_OBJ_SLOT, NullValue());
         setFixedSlot(EXPRESSION_STACK_SLOT, NullValue());
         setFixedSlot(YIELD_INDEX_SLOT, NullValue());
-        setFixedSlot(NEWTARGET_SLOT, NullValue());
     }
 
     static size_t offsetOfCalleeSlot() {
         return getFixedSlotOffset(CALLEE_SLOT);
     }
     static size_t offsetOfThisSlot() {
         return getFixedSlotOffset(THIS_SLOT);
     }
@@ -200,19 +187,16 @@ class GeneratorObject : public NativeObj
         return getFixedSlotOffset(ARGS_OBJ_SLOT);
     }
     static size_t offsetOfYieldIndexSlot() {
         return getFixedSlotOffset(YIELD_INDEX_SLOT);
     }
     static size_t offsetOfExpressionStackSlot() {
         return getFixedSlotOffset(EXPRESSION_STACK_SLOT);
     }
-    static size_t offsetOfNewTargetSlot() {
-        return getFixedSlotOffset(NEWTARGET_SLOT);
-    }
 };
 
 class LegacyGeneratorObject : public GeneratorObject
 {
   public:
     static const Class class_;
 
     static bool close(JSContext* cx, HandleObject obj);
--- 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
@@ -672,32 +672,31 @@ js::Invoke(JSContext* cx, CallArgs args,
     MOZ_ASSERT(!cx->zone()->types.activeAnalysis);
 
     /* Perform GC if necessary on exit from the function. */
     AutoGCIfRequested gcIfRequested(cx->runtime());
 
     /* MaybeConstruct is a subset of InitialFrameFlags */
     InitialFrameFlags initial = (InitialFrameFlags) construct;
 
-    unsigned skipForCallee = args.length() + 1 + (construct == CONSTRUCT);
     if (args.calleev().isPrimitive())
-        return ReportIsNotFunction(cx, args.calleev(), skipForCallee, construct);
+        return ReportIsNotFunction(cx, args.calleev(), args.length() + 1, construct);
 
     const Class* clasp = args.callee().getClass();
 
     /* Invoke non-functions. */
     if (MOZ_UNLIKELY(clasp != &JSFunction::class_)) {
 #if JS_HAS_NO_SUCH_METHOD
         if (MOZ_UNLIKELY(clasp == &js_NoSuchMethodClass))
             return NoSuchMethod(cx, args.length(), args.base());
 #endif
         MOZ_ASSERT_IF(construct, !args.callee().constructHook());
         JSNative call = args.callee().callHook();
         if (!call)
-            return ReportIsNotFunction(cx, args.calleev(), skipForCallee, construct);
+            return ReportIsNotFunction(cx, args.calleev(), args.length() + 1, construct);
         return CallJSNative(cx, call, args);
     }
 
     /* Invoke native functions. */
     JSFunction* fun = &args.callee().as<JSFunction>();
     if (fun->isNative()) {
         MOZ_ASSERT_IF(construct, !fun->isConstructor());
         return CallJSNative(cx, fun->native(), args);
@@ -766,61 +765,54 @@ js::Invoke(JSContext* cx, const Value& t
 
 bool
 js::InvokeConstructor(JSContext* cx, CallArgs args)
 {
     MOZ_ASSERT(!JSFunction::class_.construct);
 
     args.setThis(MagicValue(JS_IS_CONSTRUCTING));
 
-    // +2 here and below to pass over |this| and |new.target|
     if (!args.calleev().isObject())
-        return ReportIsNotFunction(cx, args.calleev(), args.length() + 2, CONSTRUCT);
-
-    MOZ_ASSERT(args.newTarget().isObject());
+        return ReportIsNotFunction(cx, args.calleev(), args.length() + 1, CONSTRUCT);
 
     JSObject& callee = args.callee();
     if (callee.is<JSFunction>()) {
         RootedFunction fun(cx, &callee.as<JSFunction>());
 
         if (!fun->isConstructor())
-            return ReportIsNotFunction(cx, args.calleev(), args.length() + 2, CONSTRUCT);
+            return ReportIsNotFunction(cx, args.calleev(), args.length() + 1, CONSTRUCT);
 
         if (fun->isNative())
             return CallJSNativeConstructor(cx, fun->native(), args);
 
         if (!Invoke(cx, args, CONSTRUCT))
             return false;
 
         MOZ_ASSERT(args.rval().isObject());
         return true;
     }
 
     JSNative construct = callee.constructHook();
     if (!construct)
-        return ReportIsNotFunction(cx, args.calleev(), args.length() + 2, CONSTRUCT);
+        return ReportIsNotFunction(cx, args.calleev(), args.length() + 1, CONSTRUCT);
 
     return CallJSNativeConstructor(cx, construct, args);
 }
 
 bool
 js::InvokeConstructor(JSContext* cx, Value fval, unsigned argc, const Value* argv,
-                      bool newTargetInArgv, MutableHandleValue rval)
+                      MutableHandleValue rval)
 {
     InvokeArgs args(cx);
-    if (!args.init(argc, true))
+    if (!args.init(argc))
         return false;
 
     args.setCallee(fval);
     args.setThis(MagicValue(JS_THIS_POISON));
     PodCopy(args.array(), argv, argc);
-    if (newTargetInArgv)
-        args.newTarget().set(argv[argc]);
-    else
-        args.newTarget().set(fval);
 
     if (!InvokeConstructor(cx, args))
         return false;
 
     rval.set(args.rval());
     return true;
 }
 
@@ -842,18 +834,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 +869,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 +909,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);
@@ -1946,16 +1937,17 @@ CASE(EnableInterruptsPseudoOpcode)
     /* Commence executing the actual opcode. */
     SANITY_CHECKS();
     DISPATCH_TO(op);
 }
 
 /* Various 1-byte no-ops. */
 CASE(JSOP_NOP)
 CASE(JSOP_UNUSED2)
+CASE(JSOP_UNUSED148)
 CASE(JSOP_BACKPATCH)
 CASE(JSOP_UNUSED150)
 CASE(JSOP_UNUSED161)
 CASE(JSOP_UNUSED162)
 CASE(JSOP_UNUSED163)
 CASE(JSOP_UNUSED164)
 CASE(JSOP_UNUSED165)
 CASE(JSOP_UNUSED166)
@@ -2894,35 +2886,26 @@ CASE(JSOP_SPREADCALL)
         cx->runtime()->spsProfiler.updatePC(script, REGS.pc);
     /* FALL THROUGH */
 
 CASE(JSOP_SPREADEVAL)
 CASE(JSOP_STRICTSPREADEVAL)
 {
     static_assert(JSOP_SPREADEVAL_LENGTH == JSOP_STRICTSPREADEVAL_LENGTH,
                   "spreadeval and strictspreadeval must be the same size");
-    bool construct = JSOp(*REGS.pc) == JSOP_SPREADNEW;
-
-    MOZ_ASSERT(REGS.stackDepth() >= 3u + construct);
-
-    HandleValue callee = REGS.stackHandleAt(-3 - construct);
-    HandleValue thisv = REGS.stackHandleAt(-2 - construct);
-    HandleValue arr = REGS.stackHandleAt(-1 - construct);
-    MutableHandleValue ret = REGS.stackHandleAt(-3 - construct);
-
-    RootedValue& newTarget = rootValue0;
-    if (construct)
-        newTarget = REGS.sp[-1];
-    else
-        newTarget = NullValue();
-
-    if (!SpreadCallOperation(cx, script, REGS.pc, thisv, callee, arr, newTarget, ret))
+    MOZ_ASSERT(REGS.stackDepth() >= 3);
+
+    HandleValue callee = REGS.stackHandleAt(-3);
+    HandleValue thisv = REGS.stackHandleAt(-2);
+    HandleValue arr = REGS.stackHandleAt(-1);
+    MutableHandleValue ret = REGS.stackHandleAt(-3);
+    if (!SpreadCallOperation(cx, script, REGS.pc, thisv, callee, arr, ret))
         goto error;
 
-    REGS.sp -= 2 + construct;
+    REGS.sp -= 2;
 }
 END_CASE(JSOP_SPREADCALL)
 
 CASE(JSOP_FUNAPPLY)
 {
     CallArgs args = CallArgsFromSp(GET_ARGC(REGS.pc), REGS.sp);
     if (!GuardFunApplyArgumentsOptimization(cx, REGS.fp(), args))
         goto error;
@@ -2931,21 +2914,20 @@ CASE(JSOP_FUNAPPLY)
 
 CASE(JSOP_NEW)
 CASE(JSOP_CALL)
 CASE(JSOP_FUNCALL)
 {
     if (REGS.fp()->hasPushedSPSFrame())
         cx->runtime()->spsProfiler.updatePC(script, REGS.pc);
 
+    MOZ_ASSERT(REGS.stackDepth() >= 2u + GET_ARGC(REGS.pc));
+    CallArgs args = CallArgsFromSp(GET_ARGC(REGS.pc), REGS.sp);
+
     bool construct = (*REGS.pc == JSOP_NEW);
-    unsigned argStackSlots = GET_ARGC(REGS.pc) + construct;
-
-    MOZ_ASSERT(REGS.stackDepth() >= 2u + GET_ARGC(REGS.pc));
-    CallArgs args = CallArgsFromSp(argStackSlots, REGS.sp, construct);
 
     JSFunction* maybeFun;
     bool isFunction = IsFunctionObject(args.calleev(), &maybeFun);
 
     /* Don't bother trying to fast-path calls to scripted non-constructors. */
     if (!isFunction || !maybeFun->isInterpreted() || !maybeFun->isConstructor()) {
         if (construct) {
             if (!InvokeConstructor(cx, args))
@@ -3415,24 +3397,22 @@ CASE(JSOP_LAMBDA)
     PUSH_OBJECT(*obj);
 }
 END_CASE(JSOP_LAMBDA)
 
 CASE(JSOP_LAMBDA_ARROW)
 {
     /* Load the specified function object literal. */
     ReservedRooted<JSFunction*> fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc)));
-    ReservedRooted<Value> thisv(&rootValue0, REGS.sp[-2]);
-    ReservedRooted<Value> newTarget(&rootValue1, REGS.sp[-1]);
-    JSObject* obj = LambdaArrow(cx, fun, REGS.fp()->scopeChain(), thisv, newTarget);
+    ReservedRooted<Value> thisv(&rootValue0, REGS.sp[-1]);
+    JSObject* obj = LambdaArrow(cx, fun, REGS.fp()->scopeChain(), thisv);
     if (!obj)
         goto error;
     MOZ_ASSERT(obj->getProto());
-    REGS.sp[-2].setObject(*obj);
-    REGS.sp--;
+    REGS.sp[-1].setObject(*obj);
 }
 END_CASE(JSOP_LAMBDA_ARROW)
 
 CASE(JSOP_CALLEE)
     MOZ_ASSERT(REGS.fp()->isNonEvalFunctionFrame());
     PUSH_COPY(REGS.fp()->calleev());
 END_CASE(JSOP_CALLEE)
 
@@ -3807,20 +3787,16 @@ CASE(JSOP_YIELD)
 CASE(JSOP_RESUME)
 {
     {
         ReservedRooted<JSObject*> gen(&rootObject0, &REGS.sp[-2].toObject());
         ReservedRooted<Value> val(&rootValue0, REGS.sp[-1]);
         // popInlineFrame expects there to be an additional value on the stack
         // to pop off, so leave "gen" on the stack.
 
-        // Again, lie to popInlineFrame. Add a "new.target" to pop later.
-        if (gen->as<GeneratorObject>().isConstructing())
-            PUSH_UNDEFINED();
-
         GeneratorObject::ResumeKind resumeKind = GeneratorObject::getResumeKind(REGS.pc);
         bool ok = GeneratorObject::resume(cx, activation, gen, val, resumeKind);
         SET_SCRIPT(REGS.fp()->script());
         if (!ok)
             goto error;
     }
     ADVANCE_AND_DISPATCH(0);
 }
@@ -3964,21 +3940,16 @@ CASE(JSOP_SUPERBASE)
             break;
         }
     }
     if (si.done())
         MOZ_CRASH("Unexpected scope chain in superbase");
 }
 END_CASE(JSOP_SUPERBASE)
 
-CASE(JSOP_NEWTARGET)
-    PUSH_COPY(REGS.fp()->newTarget());
-    MOZ_ASSERT(REGS.sp[-1].isObject() || REGS.sp[-1].isUndefined());
-END_CASE(JSOP_NEWTARGET)
-
 DEFAULT()
 {
     char numBuf[12];
     JS_snprintf(numBuf, sizeof numBuf, "%d", *REGS.pc);
     JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                          JSMSG_BAD_BYTECODE, numBuf);
     goto error;
 }
@@ -4168,29 +4139,27 @@ js::Lambda(JSContext* cx, HandleFunction
     if (!clone)
         return nullptr;
 
     MOZ_ASSERT(fun->global() == clone->global());
     return clone;
 }
 
 JSObject*
-js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv,
-                HandleValue newTargetv)
+js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv)
 {
     MOZ_ASSERT(fun->isArrow());
 
     RootedObject clone(cx, CloneFunctionObjectIfNotSingleton(cx, fun, parent, nullptr,
                                                              TenuredObject));
     if (!clone)
         return nullptr;
 
     MOZ_ASSERT(clone->as<JSFunction>().isArrow());
     clone->as<JSFunction>().setExtendedSlot(0, thisv);
-    clone->as<JSFunction>().setExtendedSlot(1, newTargetv);
 
     MOZ_ASSERT(fun->global() == clone->global());
     return clone;
 }
 
 bool
 js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject scopeChain,
                     HandleFunction funArg)
@@ -4552,55 +4521,49 @@ js::InitGetterSetterOperation(JSContext*
     if (!ValueToId<CanGC>(cx, idval, &id))
         return false;
 
     return InitGetterSetterOperation(cx, pc, obj, id, val);
 }
 
 bool
 js::SpreadCallOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue thisv,
-                        HandleValue callee, HandleValue arr, HandleValue newTarget, MutableHandleValue res)
+                        HandleValue callee, HandleValue arr, MutableHandleValue res)
 {
     RootedArrayObject aobj(cx, &arr.toObject().as<ArrayObject>());
     uint32_t length = aobj->length();
     JSOp op = JSOp(*pc);
-    bool constructing = op == JSOP_SPREADNEW;
 
     if (length > ARGS_LENGTH_MAX) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             constructing ? JSMSG_TOO_MANY_CON_SPREADARGS
-                                          : JSMSG_TOO_MANY_FUN_SPREADARGS);
+                             op == JSOP_SPREADNEW ? JSMSG_TOO_MANY_CON_SPREADARGS
+                                                  : JSMSG_TOO_MANY_FUN_SPREADARGS);
         return false;
     }
 
 #ifdef DEBUG
     // The object must be an array with dense elements and no holes. Baseline's
     // optimized spread call stubs rely on this.
     MOZ_ASSERT(aobj->getDenseInitializedLength() == length);
     MOZ_ASSERT(!aobj->isIndexed());
     for (uint32_t i = 0; i < length; i++)
         MOZ_ASSERT(!aobj->getDenseElement(i).isMagic());
 #endif
 
     InvokeArgs args(cx);
 
-    if (!args.init(length, constructing))
+    if (!args.init(length))
         return false;
 
     args.setCallee(callee);
     args.setThis(thisv);
 
     if (!GetElements(cx, aobj, length, args.array()))
         return false;
 
-    if (constructing) {
-        MOZ_ASSERT(newTarget.isObject());
-        args.newTarget().set(newTarget);
-    }
-
     switch (op) {
       case JSOP_SPREADNEW:
         if (!InvokeConstructor(cx, args))
             return false;
         break;
       case JSOP_SPREADCALL:
         if (!Invoke(cx, args))
             return false;
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -90,28 +90,27 @@ InvokeSetter(JSContext* cx, const Value&
  * (e.g. 'new') handling the the creation of the new 'this' object.
  */
 extern bool
 InvokeConstructor(JSContext* cx, CallArgs args);
 
 /* See the fval overload of Invoke. */
 extern bool
 InvokeConstructor(JSContext* cx, Value fval, unsigned argc, const Value* argv,
-                  bool newTargetInArgv, MutableHandleValue rval);
+                  MutableHandleValue rval);
 
 /*
  * 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;
@@ -351,18 +345,17 @@ GetScopeName(JSContext* cx, HandleObject
 bool
 GetScopeNameForTypeOf(JSContext* cx, HandleObject obj, HandlePropertyName name,
                       MutableHandleValue vp);
 
 JSObject*
 Lambda(JSContext* cx, HandleFunction fun, HandleObject parent);
 
 JSObject*
-LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv,
-            HandleValue newTargetv);
+LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv);
 
 bool
 GetElement(JSContext* cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
 
 bool
 CallElement(JSContext* cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
 
 bool
@@ -438,17 +431,17 @@ EnterWithOperation(JSContext* cx, Abstra
 
 
 bool
 InitGetterSetterOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleValue idval,
                           HandleObject val);
 
 bool
 SpreadCallOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue thisv,
-                    HandleValue callee, HandleValue arr, HandleValue newTarget, MutableHandleValue res);
+                    HandleValue callee, HandleValue arr, MutableHandleValue res);
 
 JSObject*
 NewObjectOperation(JSContext* cx, HandleScript script, jsbytecode* pc,
                    NewObjectKind newKind = GenericObject);
 
 JSObject*
 NewObjectOperationWithTemplate(JSContext* cx, HandleObject templateObject);
 
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -386,19 +386,19 @@ 1234567890123456789012345678901234567890
     /*
      * spreadcall variant of JSOP_NEW
      *
      * Invokes 'callee' as a constructor with 'this' and 'args', pushes the
      * return value onto the stack.
      *   Category: Statements
      *   Type: Function
      *   Operands:
-     *   Stack: callee, this, args, newTarget => rval
+     *   Stack: callee, this, args => rval
      */ \
-    macro(JSOP_SPREADNEW, 42, "spreadnew",  NULL,         1,  4,  1, JOF_BYTE|JOF_INVOKE|JOF_TYPESET) \
+    macro(JSOP_SPREADNEW, 42, "spreadnew",  NULL,         1,  3,  1, JOF_BYTE|JOF_INVOKE|JOF_TYPESET) \
     /*
      * spreadcall variant of JSOP_EVAL
      *
      * Invokes 'eval' with 'args' and pushes the return value onto the stack.
      *
      * If 'eval' in global scope is not original one, invokes the function
      * with 'this' and 'args', and pushes return value onto the stack.
      *   Category: Statements
@@ -761,18 +761,18 @@ 1234567890123456789012345678901234567890
     macro(JSOP_POP,       81, "pop",        NULL,         1,  1,  0,  JOF_BYTE) \
     \
     /*
      * Invokes 'callee' as a constructor with 'this' and 'args', pushes return
      * value onto the stack.
      *   Category: Statements
      *   Type: Function
      *   Operands: uint16_t argc
-     *   Stack: callee, this, args[0], ..., args[argc-1], newTarget => rval
-     *   nuses: (argc+3)
+     *   Stack: callee, this, args[0], ..., args[argc-1] => rval
+     *   nuses: (argc+2)
      */ \
     macro(JSOP_NEW,       82, js_new_str,   NULL,         3, -1,  1,  JOF_UINT16|JOF_INVOKE|JOF_TYPESET) \
     /*
      * Pushes newly created object onto the stack with provided [[Prototype]].
      *
      *   Category: Literals
      *   Type: Object
      *   Operands:
@@ -1335,17 +1335,17 @@ 1234567890123456789012345678901234567890
     /*
      * Pops the top of stack value as 'this', pushes an arrow function with
      * 'this' onto the stack.
      *   Category: Statements
      *   Type: Function
      *   Operands: uint32_t funcIndex
      *   Stack: this => obj
      */ \
-    macro(JSOP_LAMBDA_ARROW, 131, "lambda_arrow", NULL,   5,  2,  1, JOF_OBJECT) \
+    macro(JSOP_LAMBDA_ARROW, 131, "lambda_arrow", NULL,   5,  1,  1, JOF_OBJECT) \
     \
     /*
      * Pushes current callee onto the stack.
      *
      * Used for named function expression self-naming, if lightweight.
      *   Category: Variables and Scopes
      *   Type: Arguments
      *   Operands:
@@ -1509,25 +1509,18 @@ 1234567890123456789012345678901234567890
      * Pops the top two values on the stack as 'val' and 'obj', defines
      * 'nameIndex' property of 'obj' as 'val', pushes 'obj' onto the stack.
      *   Category: Literals
      *   Type: Object
      *   Operands: uint32_t nameIndex
      *   Stack: obj, val => obj
      */ \
     macro(JSOP_INITHIDDENPROP, 147,"inithiddenprop", NULL, 5,  2,  1,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) \
-    /*
-     * Push "new.target"
-     *
-     *  Category: Variables and Scopes
-     *  Type: Arguments
-     *  Operands:
-     *  Stack: => new.target
-     */ \
-    macro(JSOP_NEWTARGET,  148, "newtarget", NULL,      1,  0,  1,  JOF_BYTE) \
+    /* Unused. */ \
+    macro(JSOP_UNUSED148,     148,"unused148", NULL,      1,  0,  0,  JOF_BYTE) \
     \
     /*
      * Placeholder opcode used during bytecode generation. This never
      * appears in a finished script. FIXME: bug 473671.
      *   Category: Statements
      *   Type: Jumps
      *   Operands: int32_t offset
      *   Stack: =>
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -287,35 +287,29 @@ InterpreterStack::getCallFrame(JSContext
         *pargv = args.array();
         uint8_t* buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value));
         return reinterpret_cast<InterpreterFrame*>(buffer);
     }
 
     // Pad any missing arguments with |undefined|.
     MOZ_ASSERT(args.length() < nformal);
 
-    bool isConstructing = *flags & InterpreterFrame::CONSTRUCTING;
-    unsigned nfunctionState = 2 + isConstructing; // callee, |this|, |new.target|
-
-    nvals += nformal + nfunctionState;
+    nvals += nformal + 2; // Include callee, |this|.
     uint8_t* buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value));
     if (!buffer)
         return nullptr;
 
     Value* argv = reinterpret_cast<Value*>(buffer);
     unsigned nmissing = nformal - args.length();
 
     mozilla::PodCopy(argv, args.base(), 2 + args.length());
     SetValueRangeToUndefined(argv + 2 + args.length(), nmissing);
 
-    if (isConstructing)
-        argv[2 + nformal] = args.newTarget();
-
     *pargv = argv + 2;
-    return reinterpret_cast<InterpreterFrame*>(argv + nfunctionState + nformal);
+    return reinterpret_cast<InterpreterFrame*>(argv + 2 + nformal);
 }
 
 MOZ_ALWAYS_INLINE bool
 InterpreterStack::pushInlineFrame(JSContext* cx, InterpreterRegs& regs, const CallArgs& args,
                                   HandleScript script, InitialFrameFlags initial)
 {
     RootedFunction callee(cx, &args.callee().as<JSFunction>());
     MOZ_ASSERT(regs.sp == args.end());
@@ -343,49 +337,44 @@ InterpreterStack::pushInlineFrame(JSCont
 
     regs.prepareToRun(*fp, script);
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 InterpreterStack::resumeGeneratorCallFrame(JSContext* cx, InterpreterRegs& regs,
                                            HandleFunction callee, HandleValue thisv,
-                                           HandleValue newTarget, HandleObject scopeChain)
+                                           HandleObject scopeChain)
 {
     MOZ_ASSERT(callee->isGenerator());
     RootedScript script(cx, callee->getOrCreateScript(cx));
     InterpreterFrame* prev = regs.fp();
     jsbytecode* prevpc = regs.pc;
     Value* prevsp = regs.sp;
     MOZ_ASSERT(prev);
 
     script->ensureNonLazyCanonicalFunction(cx);
 
     LifoAlloc::Mark mark = allocator_.mark();
 
-    bool constructing = newTarget.isObject();
-
-    // Include callee, |this|, and maybe |new.target|
+    // Include callee, |this|.
     unsigned nformal = callee->nargs();
-    unsigned nvals = 2 + constructing + nformal + script->nslots();
+    unsigned nvals = 2 + nformal + script->nslots();
 
     uint8_t* buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value));
     if (!buffer)
         return false;
 
     Value* argv = reinterpret_cast<Value*>(buffer) + 2;
     argv[-2] = ObjectValue(*callee);
     argv[-1] = thisv;
     SetValueRangeToUndefined(argv, nformal);
-    if (constructing)
-        argv[nformal] = newTarget;
 
-    InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(argv + nformal + constructing);
-    InterpreterFrame::Flags flags = constructing ? ToFrameFlags(INITIAL_CONSTRUCT)
-                                                 : ToFrameFlags(INITIAL_NONE);
+    InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(argv + nformal);
+    InterpreterFrame::Flags flags = ToFrameFlags(INITIAL_NONE);
     fp->mark_ = mark;
     fp->initCallFrame(cx, prev, prevpc, prevsp, *callee, script, argv, 0, flags);
     fp->resumeGeneratorFrame(scopeChain);
 
     regs.prepareToRun(*fp, script);
     return true;
 }
 
@@ -816,26 +805,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);
 }
 
@@ -965,20 +944,20 @@ InterpreterActivation::popInlineFrame(In
     MOZ_ASSERT(regs_.fp() == frame);
     MOZ_ASSERT(regs_.fp() != entryFrame_);
 
     cx_->asJSContext()->runtime()->interpreterStack().popInlineFrame(regs_);
 }
 
 inline bool
 InterpreterActivation::resumeGeneratorFrame(HandleFunction callee, HandleValue thisv,
-                                            HandleValue newTarget, HandleObject scopeChain)
+                                            HandleObject scopeChain)
 {
     InterpreterStack& stack = cx_->asJSContext()->runtime()->interpreterStack();
-    if (!stack.resumeGeneratorCallFrame(cx_->asJSContext(), regs_, callee, thisv, newTarget, scopeChain))
+    if (!stack.resumeGeneratorCallFrame(cx_->asJSContext(), regs_, callee, thisv, scopeChain))
         return false;
 
     MOZ_ASSERT(regs_.fp()->script()->compartment() == compartment_);
     return true;
 }
 
 inline JSContext*
 AsmJSActivation::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;
-
-    // newTarget = NullValue is an initial sentinel for "please fill me in from the stack".
-    // It should never be passed from Ion code.
-    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;
             }
         }
     }
 
-    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;
@@ -280,17 +270,17 @@ InterpreterFrame::epilogue(JSContext* cx
                       scopeChain()->as<CallObject>().callee().nonLazyScript() == script);
     } else {
         AssertDynamicScopeMatchesStaticScope(cx, script, scopeChain());
     }
 
     if (MOZ_UNLIKELY(cx->compartment()->isDebuggee()))
         DebugScopes::onPopCall(this, cx);
 
-    if (!fun()->isGenerator() && isConstructing() && thisValue().isObject() && returnValue().isPrimitive())
+    if (isConstructing() && thisValue().isObject() && returnValue().isPrimitive())
         setReturnValue(ObjectValue(constructorThis()));
 }
 
 bool
 InterpreterFrame::pushBlock(JSContext* cx, StaticBlockObject& block)
 {
     MOZ_ASSERT(block.needsClone());
 
@@ -402,20 +392,20 @@ InterpreterFrame::markValues(JSTracer* t
 
         // Mark live locals.
         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");
+        TraceRootRange(trc, argc + 2, 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
@@ -7,17 +7,16 @@
 #ifndef vm_Stack_h
 #define vm_Stack_h
 
 #include "mozilla/Atomics.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "jsfun.h"
 #include "jsscript.h"
-#include "jsutil.h"
 
 #include "asmjs/AsmJSFrameIterator.h"
 #include "jit/JitFrameIterator.h"
 #ifdef CHECK_OSIPOINT_REGISTERS
 #include "jit/Registers.h" // for RegisterDump
 #endif
 
 struct JSCompartment;
@@ -199,18 +198,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 +399,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).
@@ -739,38 +735,16 @@ class InterpreterFrame
         return argv()[-2];
     }
 
     CallReceiver callReceiver() const {
         return CallReceiverFromArgv(argv());
     }
 
     /*
-     * 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];
-
-        if (callee().isArrow())
-            return callee().getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
-
-        if (isConstructing()) {
-            unsigned pushedArgs = Max(numFormalArgs(), numActualArgs());
-            return argv()[pushedArgs];
-        }
-        return UndefinedValue();
-    }
-
-    /*
      * Frame compartment
      *
      * A stack frame's compartment is the frame's containing context's
      * compartment when the frame was pushed.
      */
 
     inline JSCompartment* compartment() const;
 
@@ -959,17 +933,17 @@ class InterpreterRegs
         fp_ = &to;
         sp = to.slots() + (from.sp - from.fp_->slots());
         pc = from.pc;
         MOZ_ASSERT(fp_);
     }
 
     void popInlineFrame() {
         pc = fp_->prevpc();
-        sp = fp_->prevsp() - fp_->numActualArgs() - 1 - fp_->isConstructing();
+        sp = fp_->prevsp() - fp_->numActualArgs() - 1;
         fp_ = fp_->prev();
         MOZ_ASSERT(fp_);
     }
     void prepareToRun(InterpreterFrame& fp, JSScript* script) {
         pc = script->code();
         sp = fp.slots() + script->nfixed();
         fp_ = &fp;
     }
@@ -1020,33 +994,33 @@ 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,
                          HandleScript script, InitialFrameFlags initial);
 
     void popInlineFrame(InterpreterRegs& regs);
 
     bool resumeGeneratorCallFrame(JSContext* cx, InterpreterRegs& regs,
                                   HandleFunction callee, HandleValue thisv,
-                                  HandleValue newTarget, HandleObject scopeChain);
+                                  HandleObject scopeChain);
 
     inline void purge(JSRuntime* rt);
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
         return allocator_.sizeOfExcludingThis(mallocSizeOf);
     }
 };
 
@@ -1054,24 +1028,22 @@ void MarkInterpreterActivations(JSRuntim
 
 /*****************************************************************************/
 
 class InvokeArgs : public JS::CallArgs
 {
     AutoValueVector v_;
 
   public:
-    explicit InvokeArgs(JSContext* cx, bool construct = false) : v_(cx) {}
+    explicit InvokeArgs(JSContext* cx) : v_(cx) {}
 
-    bool init(unsigned argc, bool construct = false) {
-        if (!v_.resize(2 + argc + construct))
+    bool init(unsigned argc) {
+        if (!v_.resize(2 + argc))
             return false;
         ImplicitCast<CallArgs>(*this) = CallArgsFromVp(argc, v_.begin());
-        // Set the internal flag, since we are not initializing from a made array
-        constructing_ = construct;
         return true;
     }
 };
 
 template <>
 struct DefaultHasher<AbstractFramePtr> {
     typedef AbstractFramePtr Lookup;
 
@@ -1244,17 +1216,17 @@ class InterpreterActivation : public Act
     inline InterpreterActivation(RunState& state, JSContext* cx, InterpreterFrame* entryFrame);
     inline ~InterpreterActivation();
 
     inline bool pushInlineFrame(const CallArgs& args, HandleScript script,
                                 InitialFrameFlags initial);
     inline void popInlineFrame(InterpreterFrame* frame);
 
     inline bool resumeGeneratorFrame(HandleFunction callee, HandleValue thisv,
-                                     HandleValue newTarget, HandleObject scopeChain);
+                                     HandleObject scopeChain);
 
     InterpreterFrame* current() const {
         return regs_.fp();
     }
     InterpreterRegs& regs() {
         return regs_;
     }
     InterpreterFrame* entryFrame() const {
@@ -1759,18 +1731,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
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -24,21 +24,21 @@ namespace js {
  * versions.  If deserialization fails, the data should be invalidated if
  * possible.
  *
  * When you change this, run make_opcode_doc.py and copy the new output into
  * this wiki page:
  *
  *  https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
  */
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 290;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 287;
 static const uint32_t XDR_BYTECODE_VERSION =
     uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
 
-static_assert(JSErr_Limit == 399,
+static_assert(JSErr_Limit == 398,
               "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
               "removed MSG_DEFs from js.msg, you should increment "
               "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
               "expected JSErr_Limit value.");
 
 class XDRBuffer {
   public:
     explicit XDRBuffer(JSContext* cx)