Permalink
Browse files

[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
  • Loading branch information...
duongnhn committed Nov 2, 2018
2 parents c565b12 + b2ee6c7 commit a53a73f43c5218e054cb384744b10d2164a45b3a
@@ -74,8 +74,8 @@ HELPERCALLCHK(Op_ConvObject, Js::JavascriptOperators::ToObject, AttrCanThrow | A
HELPERCALLCHK(Op_NewUnscopablesWrapperObject, Js::JavascriptOperators::ToUnscopablesWrapperObject, AttrCanThrow | AttrCanNotBeReentrant)
HELPERCALLCHK(SetComputedNameVar, Js::JavascriptOperators::OP_SetComputedNameVar, AttrCanNotBeReentrant)
HELPERCALLCHK(Op_UnwrapWithObj, Js::JavascriptOperators::OP_UnwrapWithObj, AttrCanNotBeReentrant)
HELPERCALLCHK(Op_ConvNumber_Full, Js::JavascriptOperators::ToNumber, AttrCanThrow)
HELPERCALLCHK(Op_ConvNumberInPlace, Js::JavascriptOperators::ToNumberInPlace, AttrCanThrow)
HELPERCALLCHK(Op_ConvNumber_Full, Js::JavascriptOperators::ToNumeric, AttrCanThrow)
HELPERCALLCHK(Op_ConvNumberInPlace, Js::JavascriptOperators::ToNumericInPlace, AttrCanThrow)
HELPERCALLCHK(Op_ConvNumber_Helper, Js::JavascriptConversion::ToNumber_Helper, 0)
HELPERCALLCHK(Op_ConvFloat_Helper, Js::JavascriptConversion::ToFloat_Helper, 0)
HELPERCALLCHK(Op_ConvNumber_FromPrimitive, Js::JavascriptConversion::ToNumber_FromPrimitive, 0)
@@ -988,10 +988,12 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
this->LowerUnaryHelperMem(instr, IR::HelperOp_ToSpreadedFunctionArgument);
break;
case Js::OpCode::Conv_Numeric:
case Js::OpCode::Conv_Num:
this->LowerConvNum(instr, noMathFastPath);
break;
case Js::OpCode::Incr_Num_A:
case Js::OpCode::Incr_A:
if (PHASE_OFF(Js::MathFastPathPhase, this->m_func) || noMathFastPath)
{
@@ -1006,6 +1008,7 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
}
break;
case Js::OpCode::Decr_Num_A:
case Js::OpCode::Decr_A:
if (PHASE_OFF(Js::MathFastPathPhase, this->m_func) || noMathFastPath)
{
@@ -10438,15 +10438,25 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
if (pnode->isUsed || fReturnValue)
{
byteCodeGenerator->StartStatement(pnode);
const Js::OpCode op = (pnode->nop == knopDecPost) ? Js::OpCode::Sub_A : Js::OpCode::Add_A;
bool isESBigIntEnabled = byteCodeGenerator->GetScriptContext()->GetConfig()->IsESBigIntEnabled();
Js::OpCode op1;
if (isESBigIntEnabled)
{
op1 = (pnode->nop == knopDecPost) ? Js::OpCode::Decr_Num_A : Js::OpCode::Incr_Num_A;
}
else
{
op1 = (pnode->nop == knopDecPost) ? Js::OpCode::Sub_A : Js::OpCode::Add_A;
}
ParseNode* pnode1 = pnode->AsParseNodeUni()->pnode1;
// Grab a register for the expression result.
funcInfo->AcquireLoc(pnode);
// Load the initial value, convert it (this is the expression result), and increment it.
EmitLoad(pnode1, byteCodeGenerator, funcInfo);
byteCodeGenerator->Writer()->Reg2(Js::OpCode::Conv_Num, pnode->location, pnode1->location);
const Js::OpCode op2 = isESBigIntEnabled ? Js::OpCode::Conv_Numeric : Js::OpCode::Conv_Num;
byteCodeGenerator->Writer()->Reg2(op2, pnode->location, pnode1->location);
// Use temporary register if lhs cannot be assigned
Js::RegSlot incDecResult = pnode1->location;
@@ -10455,10 +10465,17 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
{
incDecResult = funcInfo->AcquireTmpRegister();
}
Js::RegSlot oneReg = funcInfo->constantToRegister.LookupWithKey(1, Js::Constants::NoRegister);
Assert(oneReg != Js::Constants::NoRegister);
byteCodeGenerator->Writer()->Reg3(op, incDecResult, pnode->location, oneReg);
if (isESBigIntEnabled)
{
byteCodeGenerator->Writer()->Reg2(op1, incDecResult, pnode->location);
}
else
{
Js::RegSlot oneReg = funcInfo->constantToRegister.LookupWithKey(1, Js::Constants::NoRegister);
Assert(oneReg != Js::Constants::NoRegister);
byteCodeGenerator->Writer()->Reg3(op1, incDecResult, pnode->location, oneReg);
}
// Store the incremented value.
EmitAssignment(nullptr, pnode1, incDecResult, byteCodeGenerator, funcInfo);
@@ -836,6 +836,9 @@ MACRO_EXTEND_WMS( Restify, Reg4, OpSideEffect|OpHasIm
MACRO_EXTEND_WMS( NewPropIdArrForCompProps, Reg1Unsigned1, OpSideEffect)
MACRO_BACKEND_ONLY(BigIntLiteral, Empty, None) // Load BigInt literal
MACRO_EXTEND_WMS(Conv_Numeric, Reg2, OpSideEffect | OpTempNumberProducing | OpTempNumberTransfer | OpTempObjectSources | OpOpndHasImplicitCall | OpProducesNumber) // Convert to Numeric. [[ToNumeric()]]
MACRO_EXTEND_WMS(Incr_Num_A, Reg2, OpTempNumberProducing | OpOpndHasImplicitCall | OpDoNotTransfer | OpTempNumberSources | OpTempObjectSources | OpCanCSE | OpPostOpDbgBailOut | OpProducesNumber) // Increment Numeric
MACRO_EXTEND_WMS(Decr_Num_A, Reg2, OpTempNumberProducing | OpOpndHasImplicitCall | OpDoNotTransfer | OpTempNumberSources | OpTempObjectSources | OpCanCSE | OpPostOpDbgBailOut | OpProducesNumber) // Increment Numeric
// All SIMD ops are backend only for non-asmjs.
#define MACRO_SIMD(opcode, asmjsLayout, opCodeAttrAsmJs, OpCodeAttr, ...) MACRO_BACKEND_ONLY(opcode, Empty, OpCodeAttr)
@@ -402,6 +402,9 @@ EXDEF2_WMS(A2A2NonVartoXXMem, Restify, JavascriptObject
EXDEF2_WMS(SET_ELEM_SLOTMem, StPropIdArrFromVar, OP_StPropIdArrFromVar)
EXDEF2_WMS(SIZEtoA1MemNonVar, NewPropIdArrForCompProps, OP_NewPropIdArrForCompProps)
EXDEF2_WMS(A1toA1Mem, Conv_Numeric, JavascriptOperators::ToNumeric)
EXDEF2_WMS(A1toA1Mem, Incr_Num_A, JavascriptMath::Increment_Numeric)
EXDEF2_WMS(A1toA1Mem, Decr_Num_A, JavascriptMath::Decrement_Numeric)
#endif
@@ -308,6 +308,15 @@ using namespace Js;
JIT_HELPER_END(Op_ConvNumberInPlace);
}
Var JavascriptOperators::ToNumericInPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
{
if (JavascriptOperators::GetTypeId(aRight) == TypeIds_BigInt)
{
return aRight;
}
return JavascriptOperators::ToNumberInPlace(aRight, scriptContext, result);
}
Var JavascriptOperators::Typeof(Var var, ScriptContext* scriptContext)
{
JIT_HELPER_REENTRANT_HEADER(Op_Typeof);
@@ -10648,6 +10657,15 @@ using namespace Js;
JIT_HELPER_END(Op_ConvNumber_Full);
}
Var JavascriptOperators::ToNumeric(Var aRight, ScriptContext* scriptContext)
{
if (JavascriptOperators::GetTypeId(aRight) == TypeIds_BigInt)
{
return aRight;
}
return JavascriptOperators::ToNumber(aRight, scriptContext);
}
BOOL JavascriptOperators::IsObject(_In_ RecyclableObject* instance)
{
return GetTypeId(instance) > TypeIds_LastJavascriptPrimitiveType;
@@ -126,6 +126,8 @@ namespace Js
static Var OP_LdCustomSpreadIteratorList(Var aRight, ScriptContext* scriptContext);
static Var ToNumber(Var aRight,ScriptContext* scriptContext);
static Var ToNumberInPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
static Var ToNumeric(Var aRight, ScriptContext* scriptContext);
static Var ToNumericInPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result);
#ifdef _M_IX86
static Var Int32ToVar(int32 value, ScriptContext* scriptContext);
static Var Int32ToVarInPlace(int32 value, ScriptContext* scriptContext, JavascriptNumber *result);
@@ -125,6 +125,24 @@ using namespace Js;
}
JIT_HELPER_TEMPLATE(Op_Decrement_Full, Op_Decrement)
Var JavascriptMath::Increment_Numeric(Var aRight, ScriptContext* scriptContext)
{
if (VarIs<JavascriptBigInt>(aRight))
{
return JavascriptBigInt::Increment(aRight);
}
return JavascriptMath::Add(aRight, TaggedInt::ToVarUnchecked(1), scriptContext);
}
Var JavascriptMath::Decrement_Numeric(Var aRight, ScriptContext* scriptContext)
{
if (VarIs<JavascriptBigInt>(aRight))
{
return JavascriptBigInt::Decrement(aRight);
}
return JavascriptMath::Subtract(aRight, TaggedInt::ToVarUnchecked(1), scriptContext);
}
Var JavascriptMath::And_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
{
JIT_HELPER_REENTRANT_HEADER(Op_And_Full);
@@ -26,6 +26,9 @@ namespace Js
static Var Decrement_Full(Var aRight,ScriptContext* scriptContext);
static Var Decrement_InPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
static Var Increment_Numeric(Var aRight, ScriptContext* scriptContext);
static Var Decrement_Numeric(Var aRight, ScriptContext* scriptContext);
static Var Negate(Var aRight,ScriptContext* scriptContext);
static Var Negate_Full(Var aRight,ScriptContext* scriptContext);
static Var Negate_InPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
@@ -97,6 +97,18 @@ var tests = [
assert.isTrue(x == y);
}
},
{
name: "With assign",
body: function () {
var x = 3n;
var y = x--;
assert.isTrue(x == 2n);
assert.isTrue(y == 3n);
y = --x;
assert.isTrue(x == 1n);
assert.isTrue(y == 1n);
}
},
];
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });
@@ -97,6 +97,18 @@ var tests = [
assert.isTrue(x == y);
}
},
{
name: "With assign",
body: function () {
var x = 3n;
var y = x++;
assert.isTrue(x == 4n);
assert.isTrue(y == 3n);
y = ++x;
assert.isTrue(x == 5n);
assert.isTrue(y == 5n);
}
},
];
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

0 comments on commit a53a73f

Please sign in to comment.