diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index c18b5d933f..442c0bcae6 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -190,8 +190,7 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, hasSingletons(false), hasTryFinally(false), emittingRunOnceLambda(false), - emitterMode(emitterMode), - functionBodyEndPosSet(false) + emitterMode(emitterMode) { MOZ_ASSERT_IF(emitterMode == LazyFunction, lazyScript); } @@ -204,7 +203,8 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, parser->tokenStream.srcCoords.lineNum(bodyPosition.begin), emitterMode) { - setFunctionBodyEndPos(bodyPosition); + setScriptStartOffsetIfUnset(bodyPosition.begin); + setFunctionBodyEndPos(bodyPosition.end); } bool @@ -1645,11 +1645,11 @@ BytecodeEmitter::tokenStream() bool BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber, ...) { - TokenPos pos = pn ? pn->pn_pos : tokenStream().currentToken().pos; + uint32_t offset = pn ? pn->pn_pos.begin : *scriptStartOffset; va_list args; va_start(args, errorNumber); - bool result = tokenStream().reportCompileErrorNumberVA(nullptr, pos.begin, JSREPORT_ERROR, + bool result = tokenStream().reportCompileErrorNumberVA(nullptr, offset, JSREPORT_ERROR, errorNumber, args); va_end(args); return result; @@ -1658,7 +1658,7 @@ BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber, ...) bool BytecodeEmitter::reportError(const mozilla::Maybe& maybeOffset, unsigned errorNumber, ...) { - uint32_t offset = maybeOffset ? *maybeOffset : tokenStream().currentToken().pos.begin; + uint32_t offset = maybeOffset ? *maybeOffset : *scriptStartOffset; va_list args; va_start(args, errorNumber); @@ -1671,11 +1671,11 @@ BytecodeEmitter::reportError(const mozilla::Maybe& maybeOffset, unsign bool BytecodeEmitter::reportExtraWarning(ParseNode* pn, unsigned errorNumber, ...) { - TokenPos pos = pn ? pn->pn_pos : tokenStream().currentToken().pos; + uint32_t offset = pn ? pn->pn_pos.begin : *scriptStartOffset; va_list args; va_start(args, errorNumber); - bool result = tokenStream().reportExtraWarningErrorNumberVA(nullptr, pos.begin, + bool result = tokenStream().reportExtraWarningErrorNumberVA(nullptr, offset, errorNumber, args); va_end(args); return result; @@ -2323,6 +2323,8 @@ BytecodeEmitter::emitSetThis(BinaryNode* setThisNode) bool BytecodeEmitter::emitScript(ParseNode* body) { + setScriptStartOffsetIfUnset(body->pn_pos.begin); + TDZCheckCache tdzCache(this); EmitterScope emitterScope(this); if (sc->isGlobalContext()) { @@ -2341,7 +2343,7 @@ BytecodeEmitter::emitScript(ParseNode* body) return false; } - setFunctionBodyEndPos(body->pn_pos); + setFunctionBodyEndPos(body->pn_pos.end); if (sc->isEvalContext() && !sc->strict() && body->is() && !body->as().isEmptyScope()) @@ -2451,6 +2453,8 @@ BytecodeEmitter::emitFunctionScript(FunctionNode* funNode) ParseNode* body = funNode->body(); FunctionBox* funbox = sc->asFunctionBox(); + setScriptStartOffsetIfUnset(body->pn_pos.begin); + // The ordering of these EmitterScopes is important. The named lambda // scope needs to enclose the function scope needs to enclose the extra // var scope. @@ -2480,7 +2484,7 @@ BytecodeEmitter::emitFunctionScript(FunctionNode* funNode) switchToMain(); } - setFunctionBodyEndPos(body->pn_pos); + setFunctionBodyEndPos(body->pn_pos.end); if (!emitTree(body)) return false; @@ -6235,8 +6239,7 @@ BytecodeEmitter::emitReturn(UnaryNode* returnNode) // We know functionBodyEndPos is set because "return" is only // valid in a function, and so we've passed through // emitFunctionScript. - MOZ_ASSERT(functionBodyEndPosSet); - if (!updateSourceCoordNotes(functionBodyEndPos)) + if (!updateSourceCoordNotes(*functionBodyEndPos)) return false; /* diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index 27f4e92cbd..64c061594b 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -236,10 +236,10 @@ struct MOZ_STACK_CLASS BytecodeEmitter const EmitterMode emitterMode; + mozilla::Maybe scriptStartOffset; + // The end location of a function body that is being emitted. - uint32_t functionBodyEndPos; - // Whether functionBodyEndPos was set. - bool functionBodyEndPosSet; + mozilla::Maybe functionBodyEndPos; /* * Note that BytecodeEmitters are magic: they own the arena "top-of-stack" @@ -350,9 +350,14 @@ struct MOZ_STACK_CLASS BytecodeEmitter return lastOpcodeIsJumpTarget() ? current->lastTarget.offset : offset(); } - void setFunctionBodyEndPos(TokenPos pos) { - functionBodyEndPos = pos.end; - functionBodyEndPosSet = true; + void setFunctionBodyEndPos(uint32_t pos) { + functionBodyEndPos = mozilla::Some(pos); + } + + void setScriptStartOffsetIfUnset(uint32_t pos) { + if (scriptStartOffset.isNothing()) { + scriptStartOffset = mozilla::Some(pos); + } } bool reportError(ParseNode* pn, unsigned errorNumber, ...);