Backed out changeset 8f94d0d72a21 (bug 1141865)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 03 Jun 2015 12:42:45 +0200
changeset 246985 28087e3f22f8740104eb345379ae2980381d5bd7
parent 246984 a837cfd8ee1e05edfcd186e1fe3a14f1c25d0bd8
child 246986 23fcf07dcd9edda77c36a361eb752ac0d6f067e4
push id28848
push userryanvm@gmail.com
push dateWed, 03 Jun 2015 20:00:13 +0000
treeherdermozilla-central@0920f2325a6d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1141865
milestone41.0a1
backs out8f94d0d72a2197cb3b1c5c063d13b836e0a2b179
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 8f94d0d72a21 (bug 1141865)
js/src/frontend/BytecodeEmitter.cpp
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/SyntaxParseHandler.h
js/src/jit-test/tests/basic/newTargetOSR.js
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/LIR-Common.h
js/src/jit/LOpcodes.h
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/js.msg
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/testNewTargetInvokeConstructor.cpp
js/src/jsast.tbl
js/src/jsopcode.cpp
js/src/jsreflect.cpp
js/src/tests/ecma_6/Class/newTargetArgumentsIntact.js
js/src/tests/ecma_6/Class/newTargetBound.js
js/src/tests/ecma_6/Class/newTargetContext.js
js/src/tests/ecma_6/Class/newTargetDVG.js
js/src/tests/ecma_6/Class/newTargetDirectInvoke.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_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/Interpreter.cpp
js/src/vm/Opcodes.h
js/src/vm/Stack.h
js/src/vm/Xdr.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -7697,21 +7697,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/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -403,17 +403,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
@@ -337,19 +337,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)
@@ -712,19 +709,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;
 
           case PNK_TYPEOFNAME:
             MOZ_ASSERT(cur->isArity(PN_UNARY));
             MOZ_ASSERT(cur->pn_kid->isKind(PNK_NAME));
             MOZ_ASSERT(!cur->pn_kid->maybeExpr());
             break;
--- 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_TYPEOFNAME:
       case PNK_TYPEOFEXPR:
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -156,17 +156,16 @@ class UpvarCookie
     F(SPREAD) \
     F(MUTATEPROTO) \
     F(CLASS) \
     F(CLASSMETHOD) \
     F(CLASSMETHODLIST) \
     F(CLASSNAMES) \
     F(SUPERPROP) \
     F(SUPERELEM) \
-    F(NEWTARGET) \
     \
     /* Unary operators. */ \
     F(TYPEOFNAME) \
     F(TYPEOFEXPR) \
     F(VOID) \
     F(NOT) \
     F(BITNOT) \
     \
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7863,46 +7863,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();
@@ -8613,54 +8604,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 (!pc->sc->isFunctionBox() || pc->sc->asFunctionBox()->isGenerator() ||
-        pc->sc->asFunctionBox()->function()->isArrow())
-    {
-        reportWithOffset(ParseError, false, begin, JSMSG_BAD_NEWTARGET);
-        return false;
-    }
-
-    newTarget = handler.newNewTarget(TokenPos(begin, pos().end));
-    return !!newTarget;
-}
-
-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,17 +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 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/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -244,17 +244,16 @@ class SyntaxParseHandler
 
     Node newSuperProperty(PropertyName* prop, const TokenPos& pos) {
         return NodeSuperProperty;
     }
 
     Node newSuperElement(Node expr, const TokenPos& pos) {
         return NodeSuperElement;
     }
-    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; }
@@ -334,19 +333,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);
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -2673,53 +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()
-{
-    MOZ_ASSERT(function());
-    frame.syncStack(0);
-
-    // if (!isConstructing()) push(undefined)
-    Label constructing, done;
-    masm.branchTestPtr(Assembler::NonZero, frame.addressOfCalleeToken(),
-                       Imm32(CalleeToken_FunctionConstructing), &constructing);
-    masm.moveValue(UndefinedValue(), R0);
-    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;
--- 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/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -10054,45 +10054,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
@@ -319,17 +319,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 visitCheckOverRecursed(LCheckOverRecursed* lir);
     void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
 
     void visitInterruptCheckImplicit(LInterruptCheckImplicit* ins);
     void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
 
     void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir);
--- 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().
@@ -9424,36 +9421,16 @@ IonBuilder::jsop_arguments()
         return true;
     }
     MOZ_ASSERT(lazyArguments_);
     current->push(lazyArguments_);
     return true;
 }
 
 bool
-IonBuilder::jsop_newtarget()
-{
-    MOZ_ASSERT(info().funMaybeLazy());
-    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);
--- 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,
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -1528,17 +1528,17 @@ 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>
@@ -7031,18 +7031,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)
-};
-
 } // namespace jit
 } // namespace js
 
 #endif /* jit_LIR_Common_h */
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -345,18 +345,17 @@
     _(AssertRangeD)                 \
     _(AssertRangeF)                 \
     _(AssertRangeV)                 \
     _(AssertResultV)                \
     _(AssertResultT)                \
     _(LexicalCheck)                 \
     _(ThrowUninitializedLexical)    \
     _(NurseryObject)                \
-    _(Debugger)                     \
-    _(NewTarget)
+    _(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
@@ -3549,23 +3549,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
@@ -291,15 +291,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);
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_Lowering_h */
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -12022,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,18 +263,17 @@ namespace jit {
     _(NewDerivedTypedObject)                                                \
     _(RecompileCheck)                                                       \
     _(MemoryBarrier)                                                        \
     _(AsmJSCompareExchangeHeap)                                             \
     _(AsmJSAtomicBinopHeap)                                                 \
     _(UnknownValue)                                                         \
     _(LexicalCheck)                                                         \
     _(ThrowUninitializedLexical)                                            \
-    _(Debugger)                                                             \
-    _(NewTarget)
+    _(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/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/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/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1269,18 +1269,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
@@ -3180,19 +3168,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)
 {
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/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/newTargetContext.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// new.target is valid inside Function() invocations
-var func = new Function("new.target");
-
-// new.target is invalid inside eval, even (for now!) eval inside a function.
-assertThrowsInstanceOf(() => eval('new.target'), SyntaxError);
-
-function evalInFunction() { eval('new.target'); }
-assertThrowsInstanceOf(() => evalInFunction(), SyntaxError);
-
-if (typeof reportCompare === "function")
-    reportCompare(0,0,"OK");
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,47 +0,0 @@
-// 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/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_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,41 +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);
-
-    // invalid (for now!) in any arrow function
-    assertError("function foo() { (() => new.target) }", SyntaxError);
-    assertError("(() => new.target))", SyntaxError);
-
-    // invalid (for now!) in generators
-    assertError("function *foo() { new.target; }", SyntaxError);
-
-    // 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/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1945,16 +1945,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)
@@ -3957,20 +3958,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());
-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;
 }
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -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.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;
@@ -736,33 +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 {
-        // new.target in eval() NYI.
-        MOZ_ASSERT(isNonEvalFunctionFrame());
-        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;
 
--- 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 = 289;
 static const uint32_t XDR_BYTECODE_VERSION =
     uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
 
-static_assert(JSErr_Limit == 401,
+static_assert(JSErr_Limit == 400,
               "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)