@@ -223,8 +223,8 @@ bool IsArguments(ParseNode *pnode)
223223}
224224
225225bool ApplyEnclosesArgs (ParseNode* fncDecl, ByteCodeGenerator* byteCodeGenerator);
226- void Emit (ParseNode * pnode, ByteCodeGenerator * byteCodeGenerator, FuncInfo * funcInfo, BOOL fReturnValue , bool isConstructorCall = false , ParseNode *bindPnode = nullptr , bool isTopLevel = false );
227- void EmitBinaryOpnds (ParseNode * pnode1, ParseNode * pnode2, ByteCodeGenerator * byteCodeGenerator, FuncInfo * funcInfo);
226+ void Emit (ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, BOOL fReturnValue , bool isConstructorCall = false , Js::RegSlot bindingNameLocation = Js::Constants::NoRegister , bool isTopLevel = false );
227+ void EmitBinaryOpnds (ParseNode* pnode1, ParseNode* pnode2, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, Js::RegSlot computedPropertyLocation = Js::Constants::NoRegister );
228228bool IsExpressionStatement (ParseNode* stmt, const Js::ScriptContext *const scriptContext);
229229void EmitInvoke (Js::RegSlot location, Js::RegSlot callObjLocation, Js::PropertyId propertyId, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo);
230230void EmitInvoke (Js::RegSlot location, Js::RegSlot callObjLocation, Js::PropertyId propertyId, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, Js::RegSlot arg1Location);
@@ -953,7 +953,7 @@ void ByteCodeGenerator::EmitTopLevelStatement(ParseNode *stmt, FuncInfo *funcInf
953953 EndStatement (stmt);
954954 }
955955
956- Emit (stmt, this , funcInfo, fReturnValue , false /* isConstructorCall*/ , nullptr /* bindPnode */ , true /* isTopLevel*/ );
956+ Emit (stmt, this , funcInfo, fReturnValue , false /* isConstructorCall*/ , Js::Constants::NoRegister /* computedPropertyLocation */ , true /* isTopLevel*/ );
957957 if (funcInfo->IsTmpReg (stmt->location ))
958958 {
959959 if (!stmt->isUsed && !fReturnValue )
@@ -8224,22 +8224,6 @@ void EmitInvoke(
82248224 byteCodeGenerator->Writer ()->CallI (Js::OpCode::CallI, location, location, 2 , callSiteId);
82258225}
82268226
8227- void EmitComputedFunctionNameVar (ParseNode *nameNode, ParseNodeFnc *exprNode, ByteCodeGenerator *byteCodeGenerator)
8228- {
8229- AssertMsg (exprNode != nullptr , " callers of this function should pass in a valid expression Node" );
8230- Assert (exprNode->HasComputedName ());
8231-
8232- if (nameNode == nullptr )
8233- {
8234- return ;
8235- }
8236-
8237- if (exprNode->pnodeName == nullptr )
8238- {
8239- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::SetComputedNameVar, exprNode->location , nameNode->location );
8240- }
8241- }
8242-
82438227void EmitMemberNode (ParseNode *memberNode, Js::RegSlot objectLocation, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, ParseNode* parentNode, bool useStore, bool * isObjectEmpty = nullptr )
82448228{
82458229 ParseNode *nameNode = memberNode->AsParseNodeBin ()->pnode1 ;
@@ -8254,6 +8238,8 @@ void EmitMemberNode(ParseNode *memberNode, Js::RegSlot objectLocation, ByteCodeG
82548238 exprNode->AsParseNodeFnc ()->SetHomeObjLocation (objectLocation);
82558239 }
82568240
8241+ Js::RegSlot computedNamePropertyKey = Js::Constants::NoRegister;
8242+
82578243 // Moved SetComputedNameVar before LdFld of prototype because loading the prototype undefers the function TypeHandler
82588244 // which makes this bytecode too late to influence the function.name.
82598245 if (nameNode->nop == knopComputedName)
@@ -8262,10 +8248,13 @@ void EmitMemberNode(ParseNode *memberNode, Js::RegSlot objectLocation, ByteCodeG
82628248 // Transparently pass the name expr
82638249 // The Emit will replace this with a temp register if necessary to preserve the value.
82648250 nameNode->location = nameNode->AsParseNodeUni ()->pnode1 ->location ;
8265- EmitBinaryOpnds (nameNode, exprNode, byteCodeGenerator, funcInfo);
8266- if (isFncDecl && !exprNode->AsParseNodeFnc ()->IsClassConstructor ())
8251+ computedNamePropertyKey = funcInfo->AcquireTmpRegister ();
8252+
8253+ EmitBinaryOpnds (nameNode, exprNode, byteCodeGenerator, funcInfo, computedNamePropertyKey);
8254+
8255+ if (isFncDecl && !exprNode->AsParseNodeFnc ()->IsClassConstructor () && exprNode->AsParseNodeFnc ()->pnodeName == nullptr )
82678256 {
8268- EmitComputedFunctionNameVar (nameNode , exprNode->AsParseNodeFnc (), byteCodeGenerator );
8257+ byteCodeGenerator-> Writer ()-> Reg2 (Js::OpCode::SetComputedNameVar , exprNode->location , computedNamePropertyKey );
82698258 }
82708259 }
82718260
@@ -8289,10 +8278,11 @@ void EmitMemberNode(ParseNode *memberNode, Js::RegSlot objectLocation, ByteCodeG
82898278 (isClassMember ? Js::OpCode::InitClassMemberSetComputedName : Js::OpCode::InitSetElemI) :
82908279 (isClassMember ? Js::OpCode::InitClassMemberComputedName : Js::OpCode::InitComputedProperty);
82918280
8292- byteCodeGenerator->Writer ()->Element (setOp, exprNode->location , objectLocation, nameNode-> location , true );
8281+ byteCodeGenerator->Writer ()->Element (setOp, exprNode->location , objectLocation, computedNamePropertyKey , true );
82938282
82948283 funcInfo->ReleaseLoc (exprNode);
82958284 funcInfo->ReleaseLoc (nameNode);
8285+ funcInfo->ReleaseTmpRegister (computedNamePropertyKey);
82968286
82978287 return ;
82988288 }
@@ -9578,7 +9568,7 @@ void EmitJumpCleanup(ParseNodeStmt *pnode, ParseNode *pnodeTarget, ByteCodeGener
95789568 }
95799569}
95809570
9581- void EmitBinaryOpnds (ParseNode *pnode1, ParseNode *pnode2, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo)
9571+ void EmitBinaryOpnds (ParseNode *pnode1, ParseNode *pnode2, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, Js::RegSlot computedPropertyLocation )
95829572{
95839573 // If opnd2 can overwrite opnd1, make sure the value of opnd1 is stashed away.
95849574 if (MayHaveSideEffectOnNode (pnode1, pnode2))
@@ -9588,15 +9578,12 @@ void EmitBinaryOpnds(ParseNode *pnode1, ParseNode *pnode2, ByteCodeGenerator *by
95889578
95899579 Emit (pnode1, byteCodeGenerator, funcInfo, false );
95909580
9591- if (pnode1->nop == knopComputedName && pnode2->nop == knopClassDecl &&
9592- (pnode2->AsParseNodeClass ()->pnodeConstructor == nullptr || pnode2->AsParseNodeClass ()->pnodeConstructor ->nop != knopVarDecl))
9593- {
9594- Emit (pnode2, byteCodeGenerator, funcInfo, false , false , pnode1);
9595- }
9596- else
9581+ if (pnode1->nop == knopComputedName && computedPropertyLocation != Js::Constants::NoRegister)
95979582 {
9598- Emit (pnode2, byteCodeGenerator, funcInfo, false );
9583+ byteCodeGenerator-> Writer ()-> Reg2 (Js::OpCode::Conv_Prop, computedPropertyLocation, pnode1-> location );
95999584 }
9585+
9586+ Emit (pnode2, byteCodeGenerator, funcInfo, false , false , computedPropertyLocation);
96009587}
96019588
96029589void EmitBinaryReference (ParseNode *pnode1, ParseNode *pnode2, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, BOOL fLoadLhs )
@@ -10142,7 +10129,7 @@ void TrackGlobalIntAssignments(ParseNodePtr pnode, ByteCodeGenerator * byteCodeG
1014210129 }
1014310130}
1014410131
10145- void Emit (ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, BOOL fReturnValue , bool isConstructorCall, ParseNode * bindPnode , bool isTopLevel)
10132+ void Emit (ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *funcInfo, BOOL fReturnValue , bool isConstructorCall, Js::RegSlot bindingNameLocation , bool isTopLevel)
1014610133{
1014710134 if (pnode == nullptr )
1014810135 {
@@ -10966,7 +10953,13 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
1096610953
1096710954 // Constructor
1096810955 Emit (pnodeClass->pnodeConstructor , byteCodeGenerator, funcInfo, false );
10969- EmitComputedFunctionNameVar (bindPnode, pnodeClass->pnodeConstructor , byteCodeGenerator);
10956+
10957+ if (bindingNameLocation != Js::Constants::NoRegister && !pnodeClass->pnodeConstructor ->pnodeName )
10958+ {
10959+ Assert (pnodeClass->pnodeConstructor ->HasComputedName ());
10960+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::SetComputedNameVar, pnodeClass->pnodeConstructor ->location , bindingNameLocation);
10961+ }
10962+
1097010963 if (pnodeClass->pnodeExtends )
1097110964 {
1097210965 byteCodeGenerator->StartStatement (pnodeClass->pnodeExtends );
0 commit comments