Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/Backend/JnHelperMethodList.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down
29 changes: 23 additions & 6 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if BigInt is considered, we generate different bytecode for post increment/decrement. Instead of: convert to number and add 1 to it, we convert value to numeric and increment it.

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;
Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions lib/Runtime/ByteCode/OpCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions lib/Runtime/Language/InterpreterHandler.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 18 additions & 0 deletions lib/Runtime/Language/JavascriptOperators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions lib/Runtime/Language/JavascriptOperators.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 18 additions & 0 deletions lib/Runtime/Math/JavascriptMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions lib/Runtime/Math/JavascriptMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions test/BigInt/decrement.js
Original file line number Diff line number Diff line change
Expand Up @@ -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" });
12 changes: 12 additions & 0 deletions test/BigInt/increment.js
Original file line number Diff line number Diff line change
Expand Up @@ -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" });