@@ -12,7 +12,7 @@ void EmitLoad(ParseNode *rhs, ByteCodeGenerator *byteCodeGenerator, FuncInfo *fu
1212void EmitCall (ParseNode* pnode, Js::RegSlot rhsLocation, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, BOOL fReturnValue , BOOL fEvaluateComponents , BOOL fHasNewTarget , Js::RegSlot overrideThisLocation = Js::Constants::NoRegister);
1313void EmitSuperFieldPatch (FuncInfo* funcInfo, ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator);
1414
15- bool EmitUseBeforeDeclaration (Symbol *sym, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo);
15+ void EmitUseBeforeDeclaration (Symbol *sym, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo);
1616void EmitUseBeforeDeclarationRuntimeError (ByteCodeGenerator *byteCodeGenerator, Js::RegSlot location);
1717void VisitClearTmpRegs (ParseNode * pnode, ByteCodeGenerator * byteCodeGenerator, FuncInfo * funcInfo);
1818
@@ -4883,6 +4883,12 @@ void ByteCodeGenerator::EmitPropStore(Js::RegSlot rhsLocation, Symbol *sym, Iden
48834883 if (sym && sym->GetNeedDeclaration () && scope->GetFunc () == funcInfo)
48844884 {
48854885 EmitUseBeforeDeclarationRuntimeError (this , Js::Constants::NoRegister);
4886+ // Intentionally continue on to do normal EmitPropStore behavior so
4887+ // that the bytecode ends up well-formed for the backend. This is
4888+ // in contrast to EmitPropLoad and EmitPropTypeof where they both
4889+ // tell EmitUseBeforeDeclarationRuntimeError to emit a LdUndef in place
4890+ // of their load and then they skip emitting their own bytecode.
4891+ // Potayto potahto.
48864892 }
48874893
48884894 if (sym == nullptr || sym->GetIsGlobal ())
@@ -5991,6 +5997,9 @@ void EmitReference(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncI
59915997 }
59925998 else
59935999 {
6000+ // EmitLoad will check for needsDeclaration and emit the Use Before Declaration error
6001+ // bytecode op as necessary, but EmitReference does not check this (by design). So we
6002+ // must manually check here.
59946003 EmitUseBeforeDeclaration (pnode->sxCall .pnodeTarget ->sxPid .sym , byteCodeGenerator, funcInfo);
59956004 EmitReference (pnode->sxCall .pnodeTarget , byteCodeGenerator, funcInfo);
59966005 }
@@ -6036,9 +6045,6 @@ void EmitDestructuredElement(ParseNode *elem, Js::RegSlot sourceLocation, ByteCo
60366045 elem->sxVar .sym ->SetNeedDeclaration (false );
60376046 break ;
60386047
6039- case knopName:
6040- break ;
6041-
60426048 default :
60436049 EmitReference (elem, byteCodeGenerator, funcInfo);
60446050 }
@@ -8862,7 +8868,7 @@ void EmitUseBeforeDeclarationRuntimeError(ByteCodeGenerator * byteCodeGenerator,
88628868 }
88638869}
88648870
8865- bool EmitUseBeforeDeclaration (Symbol *sym, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo)
8871+ void EmitUseBeforeDeclaration (Symbol *sym, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo)
88668872{
88678873 // Don't emit static use-before-declaration error in a closure or dynamic scope case. We detect such cases with dynamic checks,
88688874 // if necessary.
@@ -8873,10 +8879,7 @@ bool EmitUseBeforeDeclaration(Symbol *sym, ByteCodeGenerator *byteCodeGenerator,
88738879 sym->GetScope ()->GetFunc () == funcInfo)
88748880 {
88758881 EmitUseBeforeDeclarationRuntimeError (byteCodeGenerator, Js::Constants::NoRegister);
8876- return true ;
88778882 }
8878-
8879- return false ;
88808883}
88818884
88828885void EmitBinary (Js::OpCode opcode, ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo)
0 commit comments