Skip to content

Commit c2d084d

Browse files
David Yangsethbrenith
authored andcommitted
implement Object Rest
1 parent 4a6461b commit c2d084d

28 files changed

+907
-114
lines changed

lib/Backend/IRBuilder.cpp

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,12 +2303,35 @@ void
23032303
IRBuilder::BuildReg4(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot,
23042304
Js::RegSlot src2RegSlot, Js::RegSlot src3RegSlot)
23052305
{
2306-
IR::Instr * instr;
2307-
Assert(newOpcode == Js::OpCode::Concat3);
2306+
IR::Instr * instr = nullptr;
2307+
Assert(newOpcode == Js::OpCode::Concat3 || newOpcode == Js::OpCode::Restify);
23082308

23092309
IR::RegOpnd * src1Opnd = this->BuildSrcOpnd(src1RegSlot);
23102310
IR::RegOpnd * src2Opnd = this->BuildSrcOpnd(src2RegSlot);
2311-
IR::RegOpnd * src3Opnd = this->BuildSrcOpnd(src3RegSlot);
2311+
IR::RegOpnd * src3Opnd = this->BuildSrcOpnd(src3RegSlot);
2312+
2313+
if (newOpcode == Js::OpCode::Restify)
2314+
{
2315+
IR::RegOpnd * src0Opnd = this->BuildSrcOpnd(dstRegSlot);
2316+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), src3Opnd, m_func);
2317+
this->AddInstr(instr, offset);
2318+
2319+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), src2Opnd, instr->GetDst(), m_func);
2320+
this->AddInstr(instr, Js::Constants::NoByteCodeOffset);
2321+
2322+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), src1Opnd, instr->GetDst(), m_func);
2323+
this->AddInstr(instr, Js::Constants::NoByteCodeOffset);
2324+
2325+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), src0Opnd, instr->GetDst(), m_func);
2326+
this->AddInstr(instr, Js::Constants::NoByteCodeOffset);
2327+
2328+
IR::Opnd *firstArg = instr->GetDst();
2329+
instr = IR::Instr::New(newOpcode, m_func);
2330+
instr->SetSrc1(firstArg);
2331+
this->AddInstr(instr, Js::Constants::NoByteCodeOffset);
2332+
return;
2333+
}
2334+
23122335
IR::RegOpnd * dstOpnd = this->BuildDstOpnd(dstRegSlot);
23132336

23142337
IR::RegOpnd * str1Opnd = InsertConvPrimStr(src1Opnd, offset, true);
@@ -2997,6 +3020,7 @@ IRBuilder::BuildReg1Unsigned1(Js::OpCode newOpcode, uint offset, Js::RegSlot R0,
29973020
dstOpnd->SetValueTypeFixed();
29983021
}
29993022
}
3023+
30003024
///----------------------------------------------------------------------------
30013025
///
30023026
/// IRBuilder::BuildReg2Int1
@@ -3424,6 +3448,29 @@ IRBuilder::BuildElementSlot(Js::OpCode newOpcode, uint32 offset, Js::RegSlot fie
34243448
}
34253449
break;
34263450

3451+
case Js::OpCode::StPropIdArrFromVar:
3452+
{
3453+
IR::RegOpnd * src0Opnd = this->BuildSrcOpnd(fieldRegSlot);
3454+
IR::RegOpnd * src1Opnd = this->BuildSrcOpnd(regSlot);
3455+
IntConstType value = slotId;
3456+
IR::IntConstOpnd * valOpnd = IR::IntConstOpnd::New(value, TyInt32, m_func);
3457+
3458+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), src1Opnd, m_func);
3459+
this->AddInstr(instr, offset);
3460+
offset = Js::Constants::NoByteCodeOffset;
3461+
3462+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), valOpnd, instr->GetDst(), m_func);
3463+
this->AddInstr(instr, offset);
3464+
3465+
instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), src0Opnd, instr->GetDst(), m_func);
3466+
this->AddInstr(instr, offset);
3467+
3468+
IR::Opnd * firstArg = instr->GetDst();
3469+
instr = IR::Instr::New(newOpcode, m_func);
3470+
instr->SetSrc1(firstArg);
3471+
break;
3472+
}
3473+
34273474
default:
34283475
AssertMsg(UNREACHED, "Unknown ElementSlot opcode");
34293476
Fatal();

lib/Backend/JnHelperMethodList.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,10 @@ HELPERCALL(SpreadArrayLiteral, Js::JavascriptArray::SpreadArrayArgs, 0)
513513
HELPERCALL(SpreadCall, Js::JavascriptFunction::EntrySpreadCall, 0)
514514

515515
HELPERCALL(SpreadObjectLiteral, Js::JavascriptObject::SpreadObjectLiteral, 0)
516+
HELPERCALL(Restify, Js::JavascriptObject::Restify, 0)
517+
HELPERCALL(NewPropIdArrForCompProps, Js::InterpreterStackFrame::OP_NewPropIdArrForCompProps, AttrCanNotBeReentrant)
518+
HELPERCALL(StPropIdArrFromVar, Js::InterpreterStackFrame::OP_StPropIdArrFromVar, 0)
519+
516520

517521
HELPERCALLCHK(LdHomeObj, Js::JavascriptOperators::OP_LdHomeObj, AttrCanNotBeReentrant)
518522
HELPERCALLCHK(LdFuncObj, Js::JavascriptOperators::OP_LdFuncObj, AttrCanNotBeReentrant)

lib/Backend/Lower.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,18 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
30943094
this->LowerBinaryHelperMem(instr, IR::HelperSpreadObjectLiteral);
30953095
break;
30963096

3097+
case Js::OpCode::Restify:
3098+
instrPrev = this->LowerRestify(instr);
3099+
break;
3100+
3101+
case Js::OpCode::NewPropIdArrForCompProps:
3102+
this->LowerUnaryHelperMem(instr, IR::HelperNewPropIdArrForCompProps);
3103+
break;
3104+
3105+
case Js::OpCode::StPropIdArrFromVar:
3106+
instrPrev = this->LowerStPropIdArrFromVar(instr);
3107+
break;
3108+
30973109
default:
30983110
#ifdef ENABLE_WASM_SIMD
30993111
if (IsSimd128Opcode(instr->m_opcode))
@@ -6872,6 +6884,30 @@ Lowerer::LowerNewScGenFuncHomeObj(IR::Instr * newScFuncInstr)
68726884
return newScFuncInstr;
68736885
}
68746886

6887+
IR::Instr *
6888+
Lowerer::LowerStPropIdArrFromVar(IR::Instr * stPropIdInstr)
6889+
{
6890+
IR::HelperCallOpnd *helperOpnd = IR::HelperCallOpnd::New(IR::HelperStPropIdArrFromVar, this->m_func);
6891+
6892+
IR::Opnd * src1 = stPropIdInstr->UnlinkSrc1();
6893+
stPropIdInstr->SetSrc1(helperOpnd);
6894+
stPropIdInstr->SetSrc2(src1);
6895+
6896+
return m_lowererMD.LowerCallHelper(stPropIdInstr);
6897+
}
6898+
6899+
IR::Instr *
6900+
Lowerer::LowerRestify(IR::Instr * newRestInstr)
6901+
{
6902+
IR::HelperCallOpnd *helperOpnd = IR::HelperCallOpnd::New(IR::HelperRestify, this->m_func);
6903+
6904+
IR::Opnd * src1 = newRestInstr->UnlinkSrc1();
6905+
newRestInstr->SetSrc1(helperOpnd);
6906+
newRestInstr->SetSrc2(src1);
6907+
6908+
return m_lowererMD.LowerCallHelper(newRestInstr);
6909+
}
6910+
68756911
///----------------------------------------------------------------------------
68766912
///
68776913
/// Lowerer::LowerScopedLdFld
@@ -8615,7 +8651,7 @@ Lowerer::LowerBinaryHelper(IR::Instr *instr, IR::JnHelperMethod helperMethod)
86158651
// instrPrev.
86168652
IR::Instr *instrPrev = nullptr;
86178653

8618-
AssertMsg((Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::Reg1Unsigned1 && !instr->GetDst()) ||
8654+
AssertMsg((Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::Reg1Unsigned1) ||
86198655
Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::Reg3 ||
86208656
Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::Reg2 ||
86218657
Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::Reg2Int1 ||

lib/Backend/Lower.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ class Lowerer
144144
IR::Instr * LowerNewScGenFunc(IR::Instr *instr);
145145
IR::Instr * LowerNewScFuncHomeObj(IR::Instr *instr);
146146
IR::Instr * LowerNewScGenFuncHomeObj(IR::Instr *instr);
147+
IR::Instr * LowerStPropIdArrFromVar(IR::Instr *instr);
148+
IR::Instr * LowerRestify(IR::Instr *instr);
147149
IR::Instr* GenerateCompleteStFld(IR::Instr* instr, bool emitFastPath, IR::JnHelperMethod monoHelperAfterFastPath, IR::JnHelperMethod polyHelperAfterFastPath,
148150
IR::JnHelperMethod monoHelperWithoutFastPath, IR::JnHelperMethod polyHelperWithoutFastPath, bool withPutFlags, Js::PropertyOperationFlags flags);
149151
bool GenerateStFldWithCachedType(IR::Instr * instrStFld, bool* continueAsHelperOut, IR::LabelInstr** labelHelperOut, IR::RegOpnd** typeOpndOut);

lib/Backend/LowerMDShared.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,18 @@ LowererMD::LowerCallHelper(IR::Instr *instrCall)
191191
IR::JnHelperMethod helperMethod = instrCall->GetSrc1()->AsHelperCallOpnd()->m_fnHelper;
192192

193193
instrCall->FreeSrc1();
194-
194+
195195
#ifndef _M_X64
196+
bool callHasDst = instrCall->GetDst() != nullptr;
196197
prevInstr = ChangeToHelperCall(instrCall, helperMethod);
197-
#endif
198-
198+
if (callHasDst)
199+
{
200+
prevInstr = prevInstr->m_prev;
201+
}
202+
Assert(prevInstr->GetSrc1()->IsHelperCallOpnd() && prevInstr->GetSrc1()->AsHelperCallOpnd()->m_fnHelper == helperMethod);
203+
#else
199204
prevInstr = instrCall;
205+
#endif
200206

201207
while (argOpnd)
202208
{
@@ -206,11 +212,14 @@ LowererMD::LowerCallHelper(IR::Instr *instrCall)
206212
Assert(regArg->m_sym->m_isSingleDef);
207213
IR::Instr *instrArg = regArg->m_sym->m_instrDef;
208214

209-
Assert(instrArg->m_opcode == Js::OpCode::ArgOut_A ||
210-
(helperMethod == IR::JnHelperMethod::HelperOP_InitCachedScope && instrArg->m_opcode == Js::OpCode::ExtendArg_A) ||
211-
(helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScFuncHomeObj && instrArg->m_opcode == Js::OpCode::ExtendArg_A) ||
212-
(helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScGenFuncHomeObj && instrArg->m_opcode == Js::OpCode::ExtendArg_A)
213-
);
215+
Assert(instrArg->m_opcode == Js::OpCode::ArgOut_A || instrArg->m_opcode == Js::OpCode::ExtendArg_A &&
216+
(
217+
helperMethod == IR::JnHelperMethod::HelperOP_InitCachedScope ||
218+
helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScFuncHomeObj ||
219+
helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScGenFuncHomeObj ||
220+
helperMethod == IR::JnHelperMethod::HelperRestify ||
221+
helperMethod == IR::JnHelperMethod::HelperStPropIdArrFromVar
222+
));
214223
prevInstr = LoadHelperArgument(prevInstr, instrArg->GetSrc1());
215224

216225
argOpnd = instrArg->GetSrc2();

lib/Backend/arm/LowerMD.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,14 @@ LowererMD::LowerCallHelper(IR::Instr *instrCall)
209209
Assert(regArg->m_sym->m_isSingleDef);
210210
IR::Instr *instrArg = regArg->m_sym->m_instrDef;
211211

212-
Assert(instrArg->m_opcode == Js::OpCode::ArgOut_A ||
213-
(helperMethod == IR::JnHelperMethod::HelperOP_InitCachedScope && instrArg->m_opcode == Js::OpCode::ExtendArg_A) ||
214-
(helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScFuncHomeObj && instrArg->m_opcode == Js::OpCode::ExtendArg_A) ||
215-
(helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScGenFuncHomeObj && instrArg->m_opcode == Js::OpCode::ExtendArg_A));
212+
Assert(instrArg->m_opcode == Js::OpCode::ArgOut_A || instrArg->m_opcode == Js::OpCode::ExtendArg_A &&
213+
(
214+
helperMethod == IR::JnHelperMethod::HelperOP_InitCachedScope ||
215+
helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScFuncHomeObj ||
216+
helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScGenFuncHomeObj ||
217+
helperMethod == IR::JnHelperMethod::HelperRestify ||
218+
helperMethod == IR::JnHelperMethod::HelperStPropIdArrFromVar
219+
));
216220
prevInstr = this->LoadHelperArgument(prevInstr, instrArg->GetSrc1());
217221

218222
argOpnd = instrArg->GetSrc2();

lib/Backend/arm64/LowerMD.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,14 @@ LowererMD::LowerCallHelper(IR::Instr *instrCall)
223223
Assert(regArg->m_sym->m_isSingleDef);
224224
IR::Instr *instrArg = regArg->m_sym->m_instrDef;
225225

226-
Assert(instrArg->m_opcode == Js::OpCode::ArgOut_A ||
227-
(helperMethod == IR::JnHelperMethod::HelperOP_InitCachedScope && instrArg->m_opcode == Js::OpCode::ExtendArg_A) ||
228-
(helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScFuncHomeObj && instrArg->m_opcode == Js::OpCode::ExtendArg_A) ||
229-
(helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScGenFuncHomeObj && instrArg->m_opcode == Js::OpCode::ExtendArg_A));
226+
Assert(instrArg->m_opcode == Js::OpCode::ArgOut_A || instrArg->m_opcode == Js::OpCode::ExtendArg_A &&
227+
(
228+
helperMethod == IR::JnHelperMethod::HelperOP_InitCachedScope ||
229+
helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScFuncHomeObj ||
230+
helperMethod == IR::JnHelperMethod::HelperScrFunc_OP_NewScGenFuncHomeObj ||
231+
helperMethod == IR::JnHelperMethod::HelperRestify ||
232+
helperMethod == IR::JnHelperMethod::HelperStPropIdArrFromVar
233+
));
230234
prevInstr = this->LoadHelperArgument(prevInstr, instrArg->GetSrc1());
231235

232236
argOpnd = instrArg->GetSrc2();

lib/Common/ConfigFlagsList.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ PHASE(All)
626626
#define DEFAULT_CONFIG_ES6Spread (true)
627627
#define DEFAULT_CONFIG_ES6String (true)
628628
#define DEFAULT_CONFIG_ES6StringPrototypeFixes (true)
629-
#define DEFAULT_CONFIG_ES2018ObjectSpread (false)
629+
#define DEFAULT_CONFIG_ES2018ObjectRestSpread (false)
630630
#ifdef COMPILE_DISABLE_ES6PrototypeChain
631631
// If ES6PrototypeChain needs to be disabled by compile flag, DEFAULT_CONFIG_ES6PrototypeChain should be false
632632
#define DEFAULT_CONFIG_ES6PrototypeChain (false)
@@ -1122,7 +1122,7 @@ FLAGPR (Boolean, ES6, ES6Rest , "Enable ES6 Rest parame
11221122
FLAGPR (Boolean, ES6, ES6Spread , "Enable ES6 Spread support" , DEFAULT_CONFIG_ES6Spread)
11231123
FLAGPR (Boolean, ES6, ES6String , "Enable ES6 String extensions" , DEFAULT_CONFIG_ES6String)
11241124
FLAGPR (Boolean, ES6, ES6StringPrototypeFixes, "Enable ES6 String.prototype fixes" , DEFAULT_CONFIG_ES6StringPrototypeFixes)
1125-
FLAGPR (Boolean, ES6, ES2018ObjectSpread , "Enable ES2018 Object Spread" , DEFAULT_CONFIG_ES2018ObjectSpread)
1125+
FLAGPR (Boolean, ES6, ES2018ObjectRestSpread , "Enable ES2018 Object Rest/Spread" , DEFAULT_CONFIG_ES2018ObjectRestSpread)
11261126

11271127
#ifndef COMPILE_DISABLE_ES6PrototypeChain
11281128
#define COMPILE_DISABLE_ES6PrototypeChain 0

0 commit comments

Comments
 (0)