Skip to content

Commit a53a73f

Browse files
committed
[MERGE #5806 @duongnhn] BigInt: support increment, decrement with assign
Merge pull request #5806 from duongnhn:user/duongn/bigint_inc_post - change incr, decr post to use incr and decr without conversion instead of add_a, dec_a - change conv_num (to number) to use conv_numeric (to numeroc) according to https://tc39.github.io/proposal-bigint/#sec-tonumeric
2 parents c565b12 + b2ee6c7 commit a53a73f

File tree

11 files changed

+99
-8
lines changed

11 files changed

+99
-8
lines changed

lib/Backend/JnHelperMethodList.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ HELPERCALLCHK(Op_ConvObject, Js::JavascriptOperators::ToObject, AttrCanThrow | A
7474
HELPERCALLCHK(Op_NewUnscopablesWrapperObject, Js::JavascriptOperators::ToUnscopablesWrapperObject, AttrCanThrow | AttrCanNotBeReentrant)
7575
HELPERCALLCHK(SetComputedNameVar, Js::JavascriptOperators::OP_SetComputedNameVar, AttrCanNotBeReentrant)
7676
HELPERCALLCHK(Op_UnwrapWithObj, Js::JavascriptOperators::OP_UnwrapWithObj, AttrCanNotBeReentrant)
77-
HELPERCALLCHK(Op_ConvNumber_Full, Js::JavascriptOperators::ToNumber, AttrCanThrow)
78-
HELPERCALLCHK(Op_ConvNumberInPlace, Js::JavascriptOperators::ToNumberInPlace, AttrCanThrow)
77+
HELPERCALLCHK(Op_ConvNumber_Full, Js::JavascriptOperators::ToNumeric, AttrCanThrow)
78+
HELPERCALLCHK(Op_ConvNumberInPlace, Js::JavascriptOperators::ToNumericInPlace, AttrCanThrow)
7979
HELPERCALLCHK(Op_ConvNumber_Helper, Js::JavascriptConversion::ToNumber_Helper, 0)
8080
HELPERCALLCHK(Op_ConvFloat_Helper, Js::JavascriptConversion::ToFloat_Helper, 0)
8181
HELPERCALLCHK(Op_ConvNumber_FromPrimitive, Js::JavascriptConversion::ToNumber_FromPrimitive, 0)

lib/Backend/Lower.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,10 +988,12 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
988988
this->LowerUnaryHelperMem(instr, IR::HelperOp_ToSpreadedFunctionArgument);
989989
break;
990990

991+
case Js::OpCode::Conv_Numeric:
991992
case Js::OpCode::Conv_Num:
992993
this->LowerConvNum(instr, noMathFastPath);
993994
break;
994995

996+
case Js::OpCode::Incr_Num_A:
995997
case Js::OpCode::Incr_A:
996998
if (PHASE_OFF(Js::MathFastPathPhase, this->m_func) || noMathFastPath)
997999
{
@@ -1006,6 +1008,7 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
10061008
}
10071009
break;
10081010

1011+
case Js::OpCode::Decr_Num_A:
10091012
case Js::OpCode::Decr_A:
10101013
if (PHASE_OFF(Js::MathFastPathPhase, this->m_func) || noMathFastPath)
10111014
{

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10438,15 +10438,25 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
1043810438
if (pnode->isUsed || fReturnValue)
1043910439
{
1044010440
byteCodeGenerator->StartStatement(pnode);
10441-
const Js::OpCode op = (pnode->nop == knopDecPost) ? Js::OpCode::Sub_A : Js::OpCode::Add_A;
10441+
bool isESBigIntEnabled = byteCodeGenerator->GetScriptContext()->GetConfig()->IsESBigIntEnabled();
10442+
Js::OpCode op1;
10443+
if (isESBigIntEnabled)
10444+
{
10445+
op1 = (pnode->nop == knopDecPost) ? Js::OpCode::Decr_Num_A : Js::OpCode::Incr_Num_A;
10446+
}
10447+
else
10448+
{
10449+
op1 = (pnode->nop == knopDecPost) ? Js::OpCode::Sub_A : Js::OpCode::Add_A;
10450+
}
1044210451
ParseNode* pnode1 = pnode->AsParseNodeUni()->pnode1;
1044310452

1044410453
// Grab a register for the expression result.
1044510454
funcInfo->AcquireLoc(pnode);
1044610455

1044710456
// Load the initial value, convert it (this is the expression result), and increment it.
1044810457
EmitLoad(pnode1, byteCodeGenerator, funcInfo);
10449-
byteCodeGenerator->Writer()->Reg2(Js::OpCode::Conv_Num, pnode->location, pnode1->location);
10458+
const Js::OpCode op2 = isESBigIntEnabled ? Js::OpCode::Conv_Numeric : Js::OpCode::Conv_Num;
10459+
byteCodeGenerator->Writer()->Reg2(op2, pnode->location, pnode1->location);
1045010460

1045110461
// Use temporary register if lhs cannot be assigned
1045210462
Js::RegSlot incDecResult = pnode1->location;
@@ -10455,10 +10465,17 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
1045510465
{
1045610466
incDecResult = funcInfo->AcquireTmpRegister();
1045710467
}
10458-
10459-
Js::RegSlot oneReg = funcInfo->constantToRegister.LookupWithKey(1, Js::Constants::NoRegister);
10460-
Assert(oneReg != Js::Constants::NoRegister);
10461-
byteCodeGenerator->Writer()->Reg3(op, incDecResult, pnode->location, oneReg);
10468+
10469+
if (isESBigIntEnabled)
10470+
{
10471+
byteCodeGenerator->Writer()->Reg2(op1, incDecResult, pnode->location);
10472+
}
10473+
else
10474+
{
10475+
Js::RegSlot oneReg = funcInfo->constantToRegister.LookupWithKey(1, Js::Constants::NoRegister);
10476+
Assert(oneReg != Js::Constants::NoRegister);
10477+
byteCodeGenerator->Writer()->Reg3(op1, incDecResult, pnode->location, oneReg);
10478+
}
1046210479

1046310480
// Store the incremented value.
1046410481
EmitAssignment(nullptr, pnode1, incDecResult, byteCodeGenerator, funcInfo);

lib/Runtime/ByteCode/OpCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,9 @@ MACRO_EXTEND_WMS( Restify, Reg4, OpSideEffect|OpHasIm
836836
MACRO_EXTEND_WMS( NewPropIdArrForCompProps, Reg1Unsigned1, OpSideEffect)
837837

838838
MACRO_BACKEND_ONLY(BigIntLiteral, Empty, None) // Load BigInt literal
839+
MACRO_EXTEND_WMS(Conv_Numeric, Reg2, OpSideEffect | OpTempNumberProducing | OpTempNumberTransfer | OpTempObjectSources | OpOpndHasImplicitCall | OpProducesNumber) // Convert to Numeric. [[ToNumeric()]]
840+
MACRO_EXTEND_WMS(Incr_Num_A, Reg2, OpTempNumberProducing | OpOpndHasImplicitCall | OpDoNotTransfer | OpTempNumberSources | OpTempObjectSources | OpCanCSE | OpPostOpDbgBailOut | OpProducesNumber) // Increment Numeric
841+
MACRO_EXTEND_WMS(Decr_Num_A, Reg2, OpTempNumberProducing | OpOpndHasImplicitCall | OpDoNotTransfer | OpTempNumberSources | OpTempObjectSources | OpCanCSE | OpPostOpDbgBailOut | OpProducesNumber) // Increment Numeric
839842

840843
// All SIMD ops are backend only for non-asmjs.
841844
#define MACRO_SIMD(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr, ...) MACRO_BACKEND_ONLY(opcode, Empty, OpCodeAttr)

lib/Runtime/Language/InterpreterHandler.inl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ EXDEF2_WMS(A2A2NonVartoXXMem, Restify, JavascriptObject
402402
EXDEF2_WMS(SET_ELEM_SLOTMem, StPropIdArrFromVar, OP_StPropIdArrFromVar)
403403
EXDEF2_WMS(SIZEtoA1MemNonVar, NewPropIdArrForCompProps, OP_NewPropIdArrForCompProps)
404404

405+
EXDEF2_WMS(A1toA1Mem, Conv_Numeric, JavascriptOperators::ToNumeric)
406+
EXDEF2_WMS(A1toA1Mem, Incr_Num_A, JavascriptMath::Increment_Numeric)
407+
EXDEF2_WMS(A1toA1Mem, Decr_Num_A, JavascriptMath::Decrement_Numeric)
405408

406409
#endif
407410

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,15 @@ using namespace Js;
308308
JIT_HELPER_END(Op_ConvNumberInPlace);
309309
}
310310

311+
Var JavascriptOperators::ToNumericInPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
312+
{
313+
if (JavascriptOperators::GetTypeId(aRight) == TypeIds_BigInt)
314+
{
315+
return aRight;
316+
}
317+
return JavascriptOperators::ToNumberInPlace(aRight, scriptContext, result);
318+
}
319+
311320
Var JavascriptOperators::Typeof(Var var, ScriptContext* scriptContext)
312321
{
313322
JIT_HELPER_REENTRANT_HEADER(Op_Typeof);
@@ -10648,6 +10657,15 @@ using namespace Js;
1064810657
JIT_HELPER_END(Op_ConvNumber_Full);
1064910658
}
1065010659

10660+
Var JavascriptOperators::ToNumeric(Var aRight, ScriptContext* scriptContext)
10661+
{
10662+
if (JavascriptOperators::GetTypeId(aRight) == TypeIds_BigInt)
10663+
{
10664+
return aRight;
10665+
}
10666+
return JavascriptOperators::ToNumber(aRight, scriptContext);
10667+
}
10668+
1065110669
BOOL JavascriptOperators::IsObject(_In_ RecyclableObject* instance)
1065210670
{
1065310671
return GetTypeId(instance) > TypeIds_LastJavascriptPrimitiveType;

lib/Runtime/Language/JavascriptOperators.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ namespace Js
126126
static Var OP_LdCustomSpreadIteratorList(Var aRight, ScriptContext* scriptContext);
127127
static Var ToNumber(Var aRight,ScriptContext* scriptContext);
128128
static Var ToNumberInPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
129+
static Var ToNumeric(Var aRight, ScriptContext* scriptContext);
130+
static Var ToNumericInPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result);
129131
#ifdef _M_IX86
130132
static Var Int32ToVar(int32 value, ScriptContext* scriptContext);
131133
static Var Int32ToVarInPlace(int32 value, ScriptContext* scriptContext, JavascriptNumber *result);

lib/Runtime/Math/JavascriptMath.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ using namespace Js;
125125
}
126126
JIT_HELPER_TEMPLATE(Op_Decrement_Full, Op_Decrement)
127127

128+
Var JavascriptMath::Increment_Numeric(Var aRight, ScriptContext* scriptContext)
129+
{
130+
if (VarIs<JavascriptBigInt>(aRight))
131+
{
132+
return JavascriptBigInt::Increment(aRight);
133+
}
134+
return JavascriptMath::Add(aRight, TaggedInt::ToVarUnchecked(1), scriptContext);
135+
}
136+
137+
Var JavascriptMath::Decrement_Numeric(Var aRight, ScriptContext* scriptContext)
138+
{
139+
if (VarIs<JavascriptBigInt>(aRight))
140+
{
141+
return JavascriptBigInt::Decrement(aRight);
142+
}
143+
return JavascriptMath::Subtract(aRight, TaggedInt::ToVarUnchecked(1), scriptContext);
144+
}
145+
128146
Var JavascriptMath::And_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
129147
{
130148
JIT_HELPER_REENTRANT_HEADER(Op_And_Full);

lib/Runtime/Math/JavascriptMath.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ namespace Js
2626
static Var Decrement_Full(Var aRight,ScriptContext* scriptContext);
2727
static Var Decrement_InPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
2828

29+
static Var Increment_Numeric(Var aRight, ScriptContext* scriptContext);
30+
static Var Decrement_Numeric(Var aRight, ScriptContext* scriptContext);
31+
2932
static Var Negate(Var aRight,ScriptContext* scriptContext);
3033
static Var Negate_Full(Var aRight,ScriptContext* scriptContext);
3134
static Var Negate_InPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);

test/BigInt/decrement.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,18 @@ var tests = [
9797
assert.isTrue(x == y);
9898
}
9999
},
100+
{
101+
name: "With assign",
102+
body: function () {
103+
var x = 3n;
104+
var y = x--;
105+
assert.isTrue(x == 2n);
106+
assert.isTrue(y == 3n);
107+
y = --x;
108+
assert.isTrue(x == 1n);
109+
assert.isTrue(y == 1n);
110+
}
111+
},
100112
];
101113

102114
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

test/BigInt/increment.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,18 @@ var tests = [
9797
assert.isTrue(x == y);
9898
}
9999
},
100+
{
101+
name: "With assign",
102+
body: function () {
103+
var x = 3n;
104+
var y = x++;
105+
assert.isTrue(x == 4n);
106+
assert.isTrue(y == 3n);
107+
y = ++x;
108+
assert.isTrue(x == 5n);
109+
assert.isTrue(y == 5n);
110+
}
111+
},
100112
];
101113

102114
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

0 commit comments

Comments
 (0)