@@ -8931,12 +8931,23 @@ void EmitStringTemplate(ParseNodeStrTemplate *pnodeStrTemplate, ByteCodeGenerato
8931
8931
ParseNode* stringNodeList = pnodeStrTemplate->pnodeStringLiterals ;
8932
8932
8933
8933
// Emit the first string and load that into the pnode location.
8934
- Emit (stringNodeList->AsParseNodeBin ()->pnode1 , byteCodeGenerator, funcInfo, false );
8934
+ // skip loading the string if it is empty
8935
+ ParseNode* firstString = stringNodeList->AsParseNodeBin ()->pnode1 ;
8936
+ bool skippedFirst = false ;
8937
+ if (firstString->AsParseNodeStr ()->pid ->Cch () == 0 )
8938
+ {
8939
+ skippedFirst = true ;
8940
+ }
8941
+ else
8942
+ {
8943
+ Emit (stringNodeList->AsParseNodeBin ()->pnode1 , byteCodeGenerator, funcInfo, false );
8935
8944
8936
- Assert (pnodeStrTemplate->location != stringNodeList->AsParseNodeBin ()->pnode1 ->location );
8945
+ Assert (pnodeStrTemplate->location != stringNodeList->AsParseNodeBin ()->pnode1 ->location );
8946
+
8947
+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, pnodeStrTemplate->location , stringNodeList->AsParseNodeBin ()->pnode1 ->location );
8948
+ funcInfo->ReleaseLoc (stringNodeList->AsParseNodeBin ()->pnode1 );
8949
+ }
8937
8950
8938
- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Ld_A, pnodeStrTemplate->location , stringNodeList->AsParseNodeBin ()->pnode1 ->location );
8939
- funcInfo->ReleaseLoc (stringNodeList->AsParseNodeBin ()->pnode1 );
8940
8951
8941
8952
ParseNode* expressionNodeList = pnodeStrTemplate->pnodeSubstitutionExpressions ;
8942
8953
ParseNode* stringNode;
@@ -8968,10 +8979,20 @@ void EmitStringTemplate(ParseNodeStrTemplate *pnodeStrTemplate, ByteCodeGenerato
8968
8979
// Emit the expression and append it to the string we're building.
8969
8980
Emit (expressionNode, byteCodeGenerator, funcInfo, false );
8970
8981
8971
- Js::RegSlot toStringLocation = funcInfo->AcquireTmpRegister ();
8972
- byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Conv_Str, toStringLocation, expressionNode->location );
8973
- byteCodeGenerator->Writer ()->Reg3 (Js::OpCode::Add_A, pnodeStrTemplate->location , pnodeStrTemplate->location , toStringLocation);
8974
- funcInfo->ReleaseTmpRegister (toStringLocation);
8982
+ // if this is the first expression AND the initial string was empty write directly to the pnodeStrTemplate location
8983
+ if (skippedFirst == true )
8984
+ {
8985
+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Conv_Str, pnodeStrTemplate->location , expressionNode->location );
8986
+ skippedFirst = false ;
8987
+ }
8988
+ else
8989
+ {
8990
+ Js::RegSlot toStringLocation = funcInfo->AcquireTmpRegister ();
8991
+ byteCodeGenerator->Writer ()->Reg2 (Js::OpCode::Conv_Str, toStringLocation, expressionNode->location );
8992
+ byteCodeGenerator->Writer ()->Reg3 (Js::OpCode::Add_A, pnodeStrTemplate->location , pnodeStrTemplate->location , toStringLocation);
8993
+ funcInfo->ReleaseTmpRegister (toStringLocation);
8994
+ }
8995
+
8975
8996
funcInfo->ReleaseLoc (expressionNode);
8976
8997
8977
8998
// Move to the next string in the list - we already got ahead of the expressions in the first string literal above.
@@ -8990,9 +9011,12 @@ void EmitStringTemplate(ParseNodeStrTemplate *pnodeStrTemplate, ByteCodeGenerato
8990
9011
8991
9012
// Emit the string node following the previous expression and append it to the string.
8992
9013
// This is either just some string in the list or it is the last string.
8993
- Emit (stringNode, byteCodeGenerator, funcInfo, false );
8994
- byteCodeGenerator->Writer ()->Reg3 (Js::OpCode::Add_A, pnodeStrTemplate->location , pnodeStrTemplate->location , stringNode->location );
8995
- funcInfo->ReleaseLoc (stringNode);
9014
+ if (stringNode->AsParseNodeStr ()->pid ->Cch () != 0 )
9015
+ {
9016
+ Emit (stringNode, byteCodeGenerator, funcInfo, false );
9017
+ byteCodeGenerator->Writer ()->Reg3 (Js::OpCode::Add_A, pnodeStrTemplate->location , pnodeStrTemplate->location , stringNode->location );
9018
+ funcInfo->ReleaseLoc (stringNode);
9019
+ }
8996
9020
}
8997
9021
}
8998
9022
}
0 commit comments