Skip to content

Commit 73fbef9

Browse files
committed
Removed the transformation from the parser. Updated bytecdoe emitter to treat async functions similar to generators
1 parent ade59a0 commit 73fbef9

31 files changed

+300
-333
lines changed

lib/Backend/BailOut.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
14371437
Js::InterpreterStackFrame* newInstance = nullptr;
14381438
Js::Var* allocation = nullptr;
14391439

1440-
if (executeFunction->IsGenerator())
1440+
if (executeFunction->IsGenerator() || executeFunction->IsAsync())
14411441
{
14421442
// If the FunctionBody is a generator then this call is being made by one of the three
14431443
// generator resuming methods: next(), throw(), or return(). They all pass the generator

lib/Backend/FlowGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ FlowGraph::Destroy(void)
10991099
// Skipping Try blocks as we have dependency on blocks to get the last instr(see below in this function)
11001100
if (!fHasTry)
11011101
{
1102-
if (this->func->GetJnFunction()->IsGenerator())
1102+
if (this->func->GetJnFunction()->IsGenerator() || this->func->GetJnFunction()->IsAsync())
11031103
{
11041104
// the label could be a yield resume label, in which case we also need to remove it from the YieldOffsetResumeLabels list
11051105
this->func->MapUntilYieldOffsetResumeLabels([this, &labelInstr](int i, const YieldOffsetResumeLabel& yorl)

lib/Backend/Func.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ Func::Func(JitArenaAllocator *alloc, CodeGenWorkItem* workItem, const Js::Functi
214214
m_nonTempLocalVars = Anew(this->m_alloc, BVSparse<JitArenaAllocator>, this->m_alloc);
215215
}
216216

217-
if (this->m_jnFunction->IsGenerator())
217+
if (this->m_jnFunction->IsGenerator() || this->m_jnFunction->IsAsync())
218218
{
219219
m_yieldOffsetResumeLabelList = YieldOffsetResumeLabelList::New(this->m_alloc);
220220
}
@@ -846,8 +846,8 @@ Func::AjustLocalVarSlotOffset()
846846
bool
847847
Func::DoGlobOptsForGeneratorFunc()
848848
{
849-
// Disable GlobOpt optimizations for generators initially. Will visit and enable each one by one.
850-
return !m_jnFunction->IsGenerator();
849+
// Disable GlobOpt optimizations for generators and asyn functions initially. Will visit and enable each one by one.
850+
return !m_jnFunction->IsGenerator() && !m_jnFunction->IsAsync();
851851
}
852852

853853
void

lib/Backend/IRBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,7 @@ IRBuilder::BuildImplicitArgIns()
13651365
void
13661366
IRBuilder::BuildGeneratorPreamble()
13671367
{
1368-
if (!this->m_func->GetJnFunction()->IsGenerator())
1368+
if (!this->m_func->GetJnFunction()->IsGenerator() && !this->m_func->GetJnFunction()->IsAsync())
13691369
{
13701370
return;
13711371
}

lib/Backend/JnHelperMethodList.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,6 @@ HELPERCALL(ScopedLdSuperCtor, Js::JavascriptOperators::OP_ScopedLdSuperCtor,
494494
HELPERCALL(SetHomeObj, Js::JavascriptOperators::OP_SetHomeObj, 0)
495495

496496
HELPERCALL(ResumeYield, Js::JavascriptOperators::OP_ResumeYield, AttrCanThrow)
497-
HELPERCALL(AsyncSpawn, Js::JavascriptOperators::OP_AsyncSpawn, AttrCanThrow)
498497

499498
#include "ExternalHelperMethodList.h"
500499

lib/Backend/Lower.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2956,10 +2956,6 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
29562956
break;
29572957
}
29582958

2959-
case Js::OpCode::AsyncSpawn:
2960-
this->LowerBinaryHelperMem(instr, IR::HelperAsyncSpawn);
2961-
break;
2962-
29632959
case Js::OpCode::FrameDisplayCheck:
29642960
instrPrev = this->LowerFrameDisplayCheck(instr);
29652961
break;
@@ -5088,7 +5084,7 @@ Lowerer::LowerNewScObjArrayNoArg(IR::Instr *newObjInstr)
50885084
void
50895085
Lowerer::LowerPrologEpilog()
50905086
{
5091-
if (m_func->GetJnFunction()->IsGenerator())
5087+
if (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync())
50925088
{
50935089
LowerGeneratorResumeJumpTable();
50945090
}
@@ -5125,7 +5121,7 @@ Lowerer::LowerPrologEpilogAsmJs()
51255121
void
51265122
Lowerer::LowerGeneratorResumeJumpTable()
51275123
{
5128-
Assert(m_func->GetJnFunction()->IsGenerator());
5124+
Assert(m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync());
51295125

51305126
IR::Instr * jumpTableInstr = m_func->m_headInstr;
51315127
AssertMsg(jumpTableInstr->IsEntryInstr(), "First instr isn't an EntryInstr...");
@@ -7572,7 +7568,7 @@ Lowerer::LoadArgumentCount(IR::Instr *const instr)
75727568
instr->SetSrc1(IR::IntConstOpnd::New(instr->m_func->actualCount, TyUint32, instr->m_func, true));
75737569
LowererMD::ChangeToAssign(instr);
75747570
}
7575-
else if (instr->m_func->GetJnFunction()->IsGenerator())
7571+
else if (instr->m_func->GetJnFunction()->IsGenerator() || instr->m_func->GetJnFunction()->IsAsync())
75767572
{
75777573
IR::SymOpnd* symOpnd = LoadCallInfo(instr);
75787574
instr->SetSrc1(symOpnd);
@@ -9611,7 +9607,7 @@ IR::Instr *Lowerer::LowerRestParameter(IR::Opnd *formalsOpnd, IR::Opnd *dstOpnd,
96119607

96129608
LoadScriptContext(helperCallInstr);
96139609

9614-
BOOL isGenerator = this->m_func->GetJnFunction()->IsGenerator();
9610+
BOOL isGenerator = this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync();
96159611

96169612
// Elements pointer = ebp + (formals count + formals offset + 1)*sizeof(Var)
96179613
IR::RegOpnd *srcOpnd = isGenerator ? generatorArgsPtrOpnd : IR::Opnd::CreateFramePointerOpnd(this->m_func);
@@ -9719,7 +9715,7 @@ Lowerer::LowerArgIn(IR::Instr *instrArgIn)
97199715
// $createRestArray
97209716
instrArgIn->InsertBefore(createRestArrayLabel);
97219717

9722-
if (m_func->GetJnFunction()->IsGenerator())
9718+
if (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync())
97239719
{
97249720
generatorArgsPtrOpnd = LoadGeneratorArgsPtr(instrArgIn);
97259721
}
@@ -9738,7 +9734,7 @@ Lowerer::LowerArgIn(IR::Instr *instrArgIn)
97389734
if (argIndex == 1)
97399735
{
97409736
// The "this" argument is not source-dependent and doesn't need to be checked.
9741-
if (m_func->GetJnFunction()->IsGenerator())
9737+
if (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync())
97429738
{
97439739
generatorArgsPtrOpnd = LoadGeneratorArgsPtr(instrArgIn);
97449740
ConvertArgOpndIfGeneratorFunction(instrArgIn, generatorArgsPtrOpnd);
@@ -9792,7 +9788,7 @@ Lowerer::LowerArgIn(IR::Instr *instrArgIn)
97929788

97939789
// Now insert all the checks and undef-assigns.
97949790

9795-
if (m_func->GetJnFunction()->IsGenerator())
9791+
if (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync())
97969792
{
97979793
generatorArgsPtrOpnd = LoadGeneratorArgsPtr(instrInsert);
97989794
}
@@ -9962,7 +9958,7 @@ Lowerer::LowerArgIn(IR::Instr *instrArgIn)
99629958
void
99639959
Lowerer::ConvertArgOpndIfGeneratorFunction(IR::Instr *instrArgIn, IR::RegOpnd *generatorArgsPtrOpnd)
99649960
{
9965-
if (this->m_func->GetJnFunction()->IsGenerator())
9961+
if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
99669962
{
99679963
// Replace stack param operand with offset into arguments array held by
99689964
// the generator object.
@@ -10668,7 +10664,7 @@ Lowerer::LoadCallInfo(IR::Instr * instrInsert)
1066810664
IR::SymOpnd * srcOpnd;
1066910665
Func * func = instrInsert->m_func;
1067010666

10671-
if (func->GetJnFunction()->IsGenerator())
10667+
if (func->GetJnFunction()->IsGenerator() || func->GetJnFunction()->IsAsync())
1067210668
{
1067310669
// Generator function arguments and ArgumentsInfo are not on the stack. Instead they
1067410670
// are accessed off the generator object (which is prm1).
@@ -18115,7 +18111,7 @@ IR::IndirOpnd*
1811518111
Lowerer::GetArgsIndirOpndForTopFunction(IR::Instr* ldElem, IR::Opnd* valueOpnd)
1811618112
{
1811718113
// Load argument set dst = [ebp + index] (or grab from the generator object if m_func is a generator function).
18118-
IR::RegOpnd *baseOpnd = m_func->GetJnFunction()->IsGenerator() ? LoadGeneratorArgsPtr(ldElem) : IR::Opnd::CreateFramePointerOpnd(m_func);
18114+
IR::RegOpnd *baseOpnd = (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync()) ? LoadGeneratorArgsPtr(ldElem) : IR::Opnd::CreateFramePointerOpnd(m_func);
1811918115
IR::IndirOpnd* argIndirOpnd = nullptr;
1812018116
// The stack looks like this:
1812118117
// ...
@@ -18129,7 +18125,7 @@ Lowerer::GetArgsIndirOpndForTopFunction(IR::Instr* ldElem, IR::Opnd* valueOpnd)
1812918125

1813018126
//actual arguments offset is LowererMD::GetFormalParamOffset() + 1 (this)
1813118127

18132-
uint16 actualOffset = m_func->GetJnFunction()->IsGenerator() ? 1 : GetFormalParamOffset() + 1; //5
18128+
uint16 actualOffset = (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync()) ? 1 : GetFormalParamOffset() + 1; //5
1813318129
Assert(actualOffset == 5 || m_func->GetJnFunction()->IsGenerator());
1813418130
if (valueOpnd->IsIntConstOpnd())
1813518131
{
@@ -20327,6 +20323,7 @@ Lowerer::GenerateSetHomeObj(IR::Instr* instrInsert)
2032720323
Func *func = instrInsert->m_func;
2032820324

2032920325
IR::LabelInstr *labelScriptFunction = IR::LabelInstr::New(Js::OpCode::Label, func, false);
20326+
IR::LabelInstr *labelForGeneratorScriptFunction = IR::LabelInstr::New(Js::OpCode::Label, func, false);
2033020327

2033120328
IR::Opnd *src2Opnd = instrInsert->UnlinkSrc2();
2033220329
IR::Opnd *src1Opnd = instrInsert->UnlinkSrc1();
@@ -20338,10 +20335,16 @@ Lowerer::GenerateSetHomeObj(IR::Instr* instrInsert)
2033820335
LowererMD::CreateAssign(funcObjRegOpnd, src1Opnd, instrInsert);
2033920336

2034020337
IR::Opnd * vtableAddressOpnd = this->LoadVTableValueOpnd(instrInsert, VTableValue::VtableJavascriptGeneratorFunction);
20338+
InsertCompareBranch(IR::IndirOpnd::New(funcObjRegOpnd, 0, TyMachPtr, func), vtableAddressOpnd,
20339+
Js::OpCode::BrEq_A, true, labelForGeneratorScriptFunction, instrInsert);
20340+
20341+
vtableAddressOpnd = this->LoadVTableValueOpnd(instrInsert, VTableValue::VtableJavascriptAsyncFunction);
2034120342
InsertCompareBranch(IR::IndirOpnd::New(funcObjRegOpnd, 0, TyMachPtr, func), vtableAddressOpnd,
2034220343
Js::OpCode::BrNeq_A, true, labelScriptFunction, instrInsert);
2034320344

20344-
indirOpnd = IR::IndirOpnd::New(funcObjRegOpnd, Js::JavascriptGeneratorFunction::GetOffsetOfScriptFunction() , TyMachPtr, func);
20345+
instrInsert->InsertBefore(labelForGeneratorScriptFunction);
20346+
20347+
indirOpnd = IR::IndirOpnd::New(funcObjRegOpnd, instrInsert->m_func->IsGeneratorFunc() ? Js::JavascriptGeneratorFunction::GetOffsetOfScriptFunction() : Js::JavascriptAsyncFunction::GetOffsetOfScriptFunction() , TyMachPtr, func);
2034520348
LowererMD::CreateAssign(funcObjRegOpnd, indirOpnd, instrInsert);
2034620349

2034720350
instrInsert->InsertBefore(labelScriptFunction);
@@ -20363,7 +20366,7 @@ Lowerer::GenerateLoadNewTarget(IR::Instr* instrInsert)
2036320366

2036420367
Assert(!func->IsInlinee());
2036520368

20366-
if (func->GetJnFunction()->IsGenerator())
20369+
if (func->GetJnFunction()->IsGenerator() || func->GetJnFunction()->IsAsync())
2036720370
{
2036820371
instrInsert->SetSrc1(opndUndefAddress);
2036920372
LowererMD::ChangeToAssign(instrInsert);
@@ -21098,7 +21101,7 @@ void Lowerer::GenerateNullOutGeneratorFrame(IR::Instr* insertInstr)
2109821101

2109921102
void Lowerer::LowerFunctionExit(IR::Instr* funcExit)
2110021103
{
21101-
if (m_func->GetJnFunction()->IsGenerator())
21104+
if (m_func->GetJnFunction()->IsGenerator() || m_func->GetJnFunction()->IsAsync())
2110221105
{
2110321106
GenerateNullOutGeneratorFrame(funcExit->m_prev);
2110421107
}

lib/Backend/amd64/LowererMDArch.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ LowererMDArch::Init(LowererMD *lowererMD)
140140
IR::Instr *
141141
LowererMDArch::LoadInputParamPtr(IR::Instr *instrInsert, IR::RegOpnd *optionalDstOpnd /* = nullptr */)
142142
{
143-
if (this->m_func->GetJnFunction()->IsGenerator())
143+
if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
144144
{
145145
IR::RegOpnd * argPtrRegOpnd = Lowerer::LoadGeneratorArgsPtr(instrInsert);
146146
IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New(argPtrRegOpnd, 1 * MachPtr, TyMachPtr, this->m_func);
@@ -380,7 +380,7 @@ LowererMDArch::LoadHeapArguments(IR::Instr *instrArgs, bool force /* = false */,
380380
this->m_func->SetArgOffset(paramSym, 2 * MachPtr);
381381
IR::Opnd * srcOpnd = IR::SymOpnd::New(paramSym, TyMachReg, func);
382382

383-
if (this->m_func->GetJnFunction()->IsGenerator())
383+
if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
384384
{
385385
// the function object for generator calls is a GeneratorVirtualScriptFunction object
386386
// and we need to pass the real JavascriptGeneratorFunction object so grab it instead
@@ -430,7 +430,7 @@ LowererMDArch::LoadFuncExpression(IR::Instr *instrFuncExpr)
430430
paramOpnd = IR::SymOpnd::New(paramSym, TyMachReg, this->m_func);
431431
}
432432

433-
if (instrFuncExpr->m_func->GetJnFunction()->IsGenerator())
433+
if (instrFuncExpr->m_func->GetJnFunction()->IsGenerator() || instrFuncExpr->m_func->GetJnFunction()->IsAsync())
434434
{
435435
// the function object for generator calls is a GeneratorVirtualScriptFunction object
436436
// and we need to return the real JavascriptGeneratorFunction object so grab it before

lib/Backend/arm/LowerMD.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,7 +1993,7 @@ LowererMD::Init(Lowerer *lowerer)
19931993
IR::Instr *
19941994
LowererMD::LoadInputParamPtr(IR::Instr * instrInsert, IR::RegOpnd * optionalDstOpnd /* = nullptr */)
19951995
{
1996-
if (this->m_func->GetJnFunction()->IsGenerator())
1996+
if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
19971997
{
19981998
IR::RegOpnd * argPtrRegOpnd = Lowerer::LoadGeneratorArgsPtr(instrInsert);
19991999
IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New(argPtrRegOpnd, 1 * MachPtr, TyMachPtr, this->m_func);
@@ -2087,7 +2087,7 @@ LowererMD::LoadStackArgPtr(IR::Instr * instr)
20872087
instr->SetSrc1(tmpOpnd);
20882088
instr->SetSrc2(IR::IntConstOpnd::New(sizeof(Js::Var), TyMachReg, this->m_func));
20892089
}
2090-
else if (this->m_func->GetJnFunction()->IsGenerator())
2090+
else if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
20912091
{
20922092
IR::Instr *instr2 = LoadInputParamPtr(instr, instr->UnlinkDst()->AsRegOpnd());
20932093
instr->Remove();

lib/Backend/i386/LowererMDArch.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ LowererMDArch::Init(LowererMD *lowererMD)
137137
IR::Instr *
138138
LowererMDArch::LoadInputParamPtr(IR::Instr *instrInsert, IR::RegOpnd *optionalDstOpnd /* = nullptr */)
139139
{
140-
if (this->m_func->GetJnFunction()->IsGenerator())
140+
if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
141141
{
142142
IR::RegOpnd * argPtrRegOpnd = Lowerer::LoadGeneratorArgsPtr(instrInsert);
143143
IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New(argPtrRegOpnd, 1 * MachPtr, TyMachPtr, this->m_func);
@@ -334,7 +334,7 @@ LowererMDArch::LoadHeapArguments(IR::Instr *instrArgs, bool force, IR::Opnd* opn
334334
this->m_func->SetArgOffset(paramSym, 2 * MachPtr);
335335
IR::Opnd *srcOpnd = IR::SymOpnd::New(paramSym, TyMachReg, func);
336336

337-
if (this->m_func->GetJnFunction()->IsGenerator())
337+
if (this->m_func->GetJnFunction()->IsGenerator() || this->m_func->GetJnFunction()->IsAsync())
338338
{
339339
// the function object for generator calls is a GeneratorVirtualScriptFunction object
340340
// and we need to pass the real JavascriptGeneratorFunction object so grab it instead
@@ -501,7 +501,7 @@ LowererMDArch::LoadFuncExpression(IR::Instr *instrFuncExpr)
501501
paramOpnd = IR::SymOpnd::New(paramSym, TyMachReg, func);
502502
}
503503

504-
if (instrFuncExpr->m_func->GetJnFunction()->IsGenerator())
504+
if (instrFuncExpr->m_func->GetJnFunction()->IsGenerator() || instrFuncExpr->m_func->GetJnFunction()->IsAsync())
505505
{
506506
// the function object for generator calls is a GeneratorVirtualScriptFunction object
507507
// and we need to return the real JavascriptGeneratorFunction object so grab it before

lib/Common/BackendApi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ enum VTableValue {
267267
VtableJavascriptRegExp,
268268
VtableScriptFunction,
269269
VtableJavascriptGeneratorFunction,
270+
VtableJavascriptAsyncFunction,
270271
VtableStackScriptFunction,
271272
VtableConcatStringMulti,
272273
VtableCompoundString,

0 commit comments

Comments
 (0)