Skip to content

Commit d65ca8e

Browse files
committed
[1.9>master] [MERGE #4796 @mrkmarron] Fixes for step-back with async
Merge pull request #4796 from mrkmarron:asyncfixes19 Add missing snapshot visit location. Fix previous line logic for inline awaits.
2 parents 0a10073 + f58e17f commit d65ca8e

13 files changed

+137
-15
lines changed

lib/Jsrt/Jsrt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4616,7 +4616,7 @@ CHAKRA_API JsTTDReplayExecution(_Inout_ JsTTDMoveMode* moveMode, _Out_ int64_t*
46164616
*moveMode = (JsTTDMoveMode)abortException.GetMoveMode();
46174617
*rootEventTime = abortException.GetTargetEventTime();
46184618

4619-
//Check if we are tracking execution and, if so, set the exception locaiton so we can access it later
4619+
//Check if we are tracking execution and, if so, set the exception location so we can access it later
46204620
if(emanager != nullptr && abortException.IsTopLevelException())
46214621
{
46224622
emanager->SetPendingTTDUnhandledException();

lib/Runtime/Debug/TTExecutionInfo.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ namespace TTD
603603
this->m_lastReturnLocation.SetExceptionLocation(this->m_callStack.Last());
604604
}
605605

606-
if(!m_lastExceptionPropagating)
606+
if(!this->m_lastExceptionPropagating)
607607
{
608608
this->m_lastExceptionLocation.SetLocationFromFrame(this->m_topLevelCallbackEventTime, this->m_callStack.Last());
609609
this->m_lastExceptionPropagating = true;
@@ -893,10 +893,15 @@ namespace TTD
893893
{
894894
int32 cIndex = fb->GetEnclosingStatementIndexFromByteCode(bytecodeOffset, true);
895895

896-
//we moved to a new statement
896+
//We moved to a new statement
897897
Js::FunctionBody::StatementMap* pstmt = fb->GetStatementMaps()->Item(cIndex);
898898
bool newstmt = (cIndex != cfinfo.CurrentStatementIndex && pstmt->byteCodeSpan.begin <= (int)bytecodeOffset && (int)bytecodeOffset <= pstmt->byteCodeSpan.end);
899-
if (newstmt)
899+
900+
//Make sure async step back is ok -- We always step back to the first location in a statement and in most cases a function body must start at the first location in a statement.
901+
//However an await can be in the middle of a statment/expression and is implicitly the start of a function body. So, we must check for that case.
902+
bool functionBodyStartUnalignedWithStatementCase = (cfinfo.CurrentStatementIndex == -1) && (pstmt->byteCodeSpan.begin != (int)bytecodeOffset);
903+
904+
if (newstmt && !functionBodyStartUnalignedWithStatementCase)
900905
{
901906
cfinfo.LastStatementIndex = cfinfo.CurrentStatementIndex;
902907
cfinfo.LastStatementLoopTime = cfinfo.CurrentStatementLoopTime;
@@ -997,9 +1002,15 @@ namespace TTD
9971002
{
9981003
SingleCallCounter cfinfoCaller = { 0 };
9991004
bool hasCaller = this->TryGetTopCallCallerCounter(cfinfoCaller);
1005+
if (hasCaller)
1006+
{
1007+
ftime = cfinfoCaller.FunctionTime;
1008+
ltime = cfinfoCaller.CurrentStatementLoopTime;
10001009

1001-
//check if we are at the first statement in the callback event
1002-
if(!hasCaller)
1010+
fbody = cfinfoCaller.Function;
1011+
statementIndex = cfinfoCaller.CurrentStatementIndex;
1012+
}
1013+
else
10031014
{
10041015
//Set the position info to the current statement and return true
10051016
noPrevious = true;
@@ -1010,14 +1021,6 @@ namespace TTD
10101021
fbody = cfinfo.Function;
10111022
statementIndex = cfinfo.CurrentStatementIndex;
10121023
}
1013-
else
1014-
{
1015-
ftime = cfinfoCaller.FunctionTime;
1016-
ltime = cfinfoCaller.CurrentStatementLoopTime;
1017-
1018-
fbody = cfinfoCaller.Function;
1019-
statementIndex = cfinfoCaller.CurrentStatementIndex;
1020-
}
10211024
}
10221025
else
10231026
{
@@ -1041,6 +1044,7 @@ namespace TTD
10411044
void ExecutionInfoManager::GetLastExecutedTimeAndPositionForDebugger(TTDebuggerSourceLocation& sourceLocation) const
10421045
{
10431046
const TTLastReturnLocationInfo& cframe = this->m_lastReturnLocation;
1047+
10441048
if(!cframe.IsDefined())
10451049
{
10461050
sourceLocation.Clear();

lib/Runtime/Library/JavascriptGeneratorFunction.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,13 @@ namespace Js
599599
}
600600
}
601601

602+
void GeneratorVirtualScriptFunction::MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor)
603+
{
604+
this->ScriptFunction::MarkVisitKindSpecificPtrs(extractor);
605+
606+
extractor->MarkVisitVar(this->realFunction);
607+
}
608+
602609
TTD::NSSnapObjects::SnapObjectType GeneratorVirtualScriptFunction::GetSnapTag_TTD() const
603610
{
604611
return TTD::NSSnapObjects::SnapObjectType::SnapGeneratorVirtualScriptFunction;

lib/Runtime/Library/JavascriptGeneratorFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ namespace Js
155155
void SetRealGeneratorFunction(JavascriptGeneratorFunction* realFunction) { this->realFunction = realFunction; }
156156

157157
#if ENABLE_TTD
158+
virtual void MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor) override;
158159
virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
159160
virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
160161
#endif

test/TTBasic/asyncAwait2.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
function resolveWait(x) {
7+
return new Promise(resolve => {
8+
WScript.SetTimeout(() => {
9+
resolve(x);
10+
}, 100);
11+
});
12+
}
13+
14+
async function awaitImm(x) {
15+
const a = await resolveWait(1);
16+
const b = await resolveWait(2);
17+
return x + a + b;
18+
}
19+
20+
awaitImm(1).then(v => {
21+
telemetryLog(v.toString(), true);
22+
emitTTDLog(ttdLogURI);
23+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
4
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
4
2+
3+
Reached end of Execution -- Exiting.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
4
2+
3+
Reached end of Execution -- Exiting.

test/TTBasic/asyncAwait3.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
function resolveWait(x) {
7+
return new Promise(resolve => {
8+
WScript.SetTimeout(() => {
9+
resolve(x);
10+
}, 100);
11+
});
12+
}
13+
14+
async function awaitLater(x) {
15+
const p_a = resolveWait(10);
16+
const p_b = resolveWait(20);
17+
return x + await p_a + await p_b;
18+
}
19+
20+
WScript.SetTimeout(function () {
21+
awaitLater(10).then(v => {
22+
telemetryLog(v.toString(), true);
23+
emitTTDLog(ttdLogURI);
24+
});
25+
}, 0);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
40

0 commit comments

Comments
 (0)