blob: 5aa5deb3c4e9896beed790d68b6e1c604ba6b495 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
namespace Js
{
#ifdef SSE2MATH
namespace SSE2
{
#endif
class JavascriptMath
{
public:
//
// Some frequently-used operations have three flavors optimized for different situations.
//
// 1. Op : Called from the interpreter loop only. Must handle all cases (may call Op_Full)
// 2. Op_Full : Called from generated code or from Op (case 1). TaggedInt cases already handled.
// 3. Op_InPlace : Called from generated code only where result may be "in-place new'd"
//
static Var Increment(Var aRight,ScriptContext* scriptContext);
static Var Increment_Full(Var aRight,ScriptContext* scriptContext);
static Var Increment_InPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
static Var Decrement(Var aRight,ScriptContext* scriptContext);
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);
static Var Not(Var aRight,ScriptContext* scriptContext);
static Var Not_Full(Var aRight,ScriptContext* scriptContext);
static Var Not_InPlace(Var aRight,ScriptContext* scriptContext, JavascriptNumber* result);
static Var Add(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Add_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Add_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var AddLeftDead(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var MulAddLeft(Var mulLeft, Var mulRight, Var addLeft, ScriptContext* scriptContext, JavascriptNumber* result);
static Var MulAddRight(Var mulLeft, Var mulRight, Var addRight, ScriptContext* scriptContext, JavascriptNumber* result);
static Var MulSubLeft(Var mulLeft, Var mulRight, Var subLeft, ScriptContext* scriptContext, JavascriptNumber* result);
static Var MulSubRight(Var mulLeft, Var mulRight, Var subRight, ScriptContext* scriptContext, JavascriptNumber* result);
static Var Subtract(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Subtract_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Subtract_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var Multiply(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Multiply_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Multiply_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var Divide(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Divide_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Divide_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var Exponentiation(Var aLeft, Var aRight, ScriptContext* scriptContext);
static Var Exponentiation_Full(Var aLeft, Var aRight, ScriptContext* scriptContext);
static Var Exponentiation_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber *result);
static Var Modulus(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Modulus_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Modulus_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var And(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var And_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var And_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var Or(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Or_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Or_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var Xor(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Xor_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Xor_InPlace(Var aLeft, Var aRight,ScriptContext* scriptContext, JavascriptNumber *result);
static Var ShiftLeft(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var ShiftLeft_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var ShiftRight(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var ShiftRight_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var ShiftRightU(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var ShiftRightU_Full(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var FinishOddDivByPow2(int32 value, ScriptContext *scriptContext);
static Var FinishOddDivByPow2_InPlace(int32 value, ScriptContext *scriptContext, JavascriptNumber* result);
static Var MaxInAnArray(RecyclableObject * function, CallInfo callInfo, ...);
static Var MinInAnArray(RecyclableObject * function, CallInfo callInfo, ...);
static double Random(ScriptContext *scriptContext);
static int32 ToInt32Core(double T1);
static uint32 ToUInt32(double value);
static int64 TryToInt64(double T1);
static int32 ToInt32_NoObjects(Var aValue, ScriptContext* scriptContext, bool& isObject);
static int32 ToInt32(Var aValue, ScriptContext* scriptContext);
static int32 ToInt32(double value);
static int32 ToInt32_Full(Var aValue, ScriptContext* scriptContext);
// different CRT versions define these with different calling conventions, so use our own method to prevent these inconsistencies
static float FloorF(float val) { return floorf(val); }
static double Floor(double val) { return floor(val); }
static float CeilF(float val) { return ceilf(val); }
static double Ceil(double val) { return ceil(val); }
private:
static Var Add_FullHelper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead);
static Var Add_FullHelper_Wrapper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead);
static double Add_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static double Subtract_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static double Multiply_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static double Divide_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static double Modulus_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static Var Add_DoubleHelper(double dblLeft, Var addRight, ScriptContext* scriptContext, JavascriptNumber* result);
static Var Add_DoubleHelper(Var addLeft, double dblRight, ScriptContext* scriptContext, JavascriptNumber* result);
static Var Subtract_DoubleHelper(double dblLeft, Var subRight, ScriptContext* scriptContext, JavascriptNumber* result);
static Var Subtract_DoubleHelper(Var subLeft, double dblRight, ScriptContext* scriptContext, JavascriptNumber* result);
static int32 And_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static double Decrement_Helper(Var aLeft, ScriptContext* scriptContext);
static double Increment_Helper(Var aLeft, ScriptContext* scriptContext);
static double Negate_Helper(Var aRight,ScriptContext* scriptContext);
static int32 Or_Helper(Var aLeft, Var aRight,ScriptContext* scriptContext);
static BOOL IsNanInfZero(double v);
static __int64 ToInt32ES5OverflowHelper(double d);
};
#ifdef SSE2MATH
}
#endif
}