| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152 |
- //-------------------------------------------------------------------------------------------------------
- // 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
- {
- Var JavascriptMath::Negate_Full(Var aRight, ScriptContext* scriptContext)
- {
- // Special case for zero. Must return -0
- if( aRight == TaggedInt::ToVarUnchecked(0) )
- {
- return scriptContext->GetLibrary()->GetNegativeZero();
- }
- double value = Negate_Helper(aRight, scriptContext);
- return JavascriptNumber::ToVarNoCheck(value, scriptContext);
- }
- Var JavascriptMath::Negate_InPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- // Special case for zero. Must return -0
- if( aRight == TaggedInt::ToVarUnchecked(0) )
- {
- return scriptContext->GetLibrary()->GetNegativeZero();
- }
- double value = Negate_Helper(aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(value, scriptContext, result);
- }
- Var JavascriptMath::Not_Full(Var aRight, ScriptContext* scriptContext)
- {
- #if _M_IX86
- AssertMsg(!TaggedInt::Is(aRight), "Should be detected");
- #endif
- int nValue = JavascriptConversion::ToInt32(aRight, scriptContext);
- return JavascriptNumber::ToVar(~nValue, scriptContext);
- }
- Var JavascriptMath::Not_InPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- AssertMsg(!TaggedInt::Is(aRight), "Should be detected");
- int nValue = JavascriptConversion::ToInt32(aRight, scriptContext);
- return JavascriptNumber::ToVarInPlace(~nValue, scriptContext, result);
- }
- Var JavascriptMath::Increment_InPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if (TaggedInt::Is(aRight))
- {
- return TaggedInt::Increment(aRight, scriptContext);
- }
- double inc = Increment_Helper(aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(inc, scriptContext, result);
- }
- Var JavascriptMath::Increment_Full(Var aRight, ScriptContext* scriptContext)
- {
- if (TaggedInt::Is(aRight))
- {
- return TaggedInt::Increment(aRight, scriptContext);
- }
- double inc = Increment_Helper(aRight, scriptContext);
- return JavascriptNumber::ToVarNoCheck(inc, scriptContext);
- }
- Var JavascriptMath::Decrement_InPlace(Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if (TaggedInt::Is(aRight))
- {
- return TaggedInt::Decrement(aRight, scriptContext);
- }
- double dec = Decrement_Helper(aRight,scriptContext);
- return JavascriptNumber::InPlaceNew(dec, scriptContext, result);
- }
- Var JavascriptMath::Decrement_Full(Var aRight, ScriptContext* scriptContext)
- {
- if (TaggedInt::Is(aRight))
- {
- return TaggedInt::Decrement(aRight, scriptContext);
- }
- double dec = Decrement_Helper(aRight,scriptContext);
- return JavascriptNumber::ToVarNoCheck(dec, scriptContext);
- }
- Var JavascriptMath::And_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- int32 value = And_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVar(value, scriptContext);
- }
- Var JavascriptMath::And_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- int32 value = And_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVarInPlace(value, scriptContext, result);
- }
- Var JavascriptMath::Or_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- int32 value = Or_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVar(value, scriptContext);
- }
- Var JavascriptMath::Or_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- int32 value = Or_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVarInPlace(value, scriptContext, result);
- }
- Var JavascriptMath::Xor_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- int32 nLeft = TaggedInt::Is(aLeft) ? TaggedInt::ToInt32(aLeft) : JavascriptConversion::ToInt32(aLeft, scriptContext);
- int32 nRight = TaggedInt::Is(aRight) ? TaggedInt::ToInt32(aRight) : JavascriptConversion::ToInt32(aRight, scriptContext);
- return JavascriptNumber::ToVar(nLeft ^ nRight,scriptContext);
- }
- Var JavascriptMath::Xor_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- int32 nLeft = TaggedInt::Is(aLeft) ? TaggedInt::ToInt32(aLeft) : JavascriptConversion::ToInt32(aLeft, scriptContext);
- int32 nRight = TaggedInt::Is(aRight) ? TaggedInt::ToInt32(aRight) : JavascriptConversion::ToInt32(aRight, scriptContext);
- return JavascriptNumber::ToVarInPlace(nLeft ^ nRight, scriptContext, result);
- }
- Var JavascriptMath::ShiftLeft_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- int32 nValue = JavascriptConversion::ToInt32(aLeft, scriptContext);
- uint32 nShift = JavascriptConversion::ToUInt32(aRight, scriptContext);
- int32 nResult = nValue << (nShift & 0x1F);
- return JavascriptNumber::ToVar(nResult,scriptContext);
- }
- Var JavascriptMath::ShiftRight_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- int32 nValue = JavascriptConversion::ToInt32(aLeft, scriptContext);
- uint32 nShift = JavascriptConversion::ToUInt32(aRight, scriptContext);
- int32 nResult = nValue >> (nShift & 0x1F);
- return JavascriptNumber::ToVar(nResult,scriptContext);
- }
- Var JavascriptMath::ShiftRightU_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- uint32 nValue = JavascriptConversion::ToUInt32(aLeft, scriptContext);
- uint32 nShift = JavascriptConversion::ToUInt32(aRight, scriptContext);
- uint32 nResult = nValue >> (nShift & 0x1F);
- return JavascriptNumber::ToVar(nResult,scriptContext);
- }
- #if FLOATVAR
- Var JavascriptMath::Add_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- Assert(aLeft != nullptr);
- Assert(aRight != nullptr);
- Assert(scriptContext != nullptr);
- Js::TypeId typeLeft = JavascriptOperators::GetTypeId(aLeft);
- Js::TypeId typeRight = JavascriptOperators::GetTypeId(aRight);
- if (typeRight == typeLeft)
- {
- // If both sides are numbers/string, then we can do the addition directly
- if(typeLeft == TypeIds_Number)
- {
- double sum = JavascriptNumber::GetValue(aLeft) + JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::ToVarNoCheck(sum, scriptContext);
- }
- else if (typeLeft == TypeIds_Integer)
- {
- __int64 sum = TaggedInt::ToInt64(aLeft) + TaggedInt::ToInt64(aRight);
- return JavascriptNumber::ToVar(sum, scriptContext);
- }
- else if (typeLeft == TypeIds_String)
- {
- return JavascriptString::Concat(JavascriptString::UnsafeFromVar(aLeft), JavascriptString::UnsafeFromVar(aRight));
- }
- }
- else if(typeLeft == TypeIds_Number && typeRight == TypeIds_Integer)
- {
- double sum = JavascriptNumber::GetValue(aLeft) + TaggedInt::ToDouble(aRight);
- return JavascriptNumber::ToVarNoCheck(sum, scriptContext);
- }
- else if(typeLeft == TypeIds_Integer && typeRight == TypeIds_Number)
- {
- double sum = TaggedInt::ToDouble(aLeft) + JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::ToVarNoCheck(sum, scriptContext);
- }
- return Add_FullHelper_Wrapper(aLeft, aRight, scriptContext, nullptr, false);
- }
- #else
- Var JavascriptMath::Add_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- Assert(aLeft != nullptr);
- Assert(aRight != nullptr);
- Assert(scriptContext != nullptr);
- Js::TypeId typeLeft = JavascriptOperators::GetTypeId(aLeft);
- Js::TypeId typeRight = JavascriptOperators::GetTypeId(aRight);
- // Handle combinations of TaggedInt and Number or String pairs directly,
- // otherwise call the helper.
- switch( typeLeft )
- {
- case TypeIds_Integer:
- {
- switch( typeRight )
- {
- case TypeIds_Integer:
- {
- // Compute the sum using integer addition, then convert to double.
- // That way there's only one int->float conversion.
- #if INT32VAR
- int64 sum = TaggedInt::ToInt64(aLeft) + TaggedInt::ToInt64(aRight);
- #else
- int32 sum = TaggedInt::ToInt32(aLeft) + TaggedInt::ToInt32(aRight);
- #endif
- return JavascriptNumber::ToVar(sum, scriptContext );
- }
- case TypeIds_Number:
- {
- double sum = TaggedInt::ToDouble(aLeft) + JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::NewInlined( sum, scriptContext );
- }
- }
- break;
- }
- case TypeIds_Number:
- {
- switch( typeRight )
- {
- case TypeIds_Integer:
- {
- double sum = JavascriptNumber::GetValue(aLeft) + TaggedInt::ToDouble(aRight);
- return JavascriptNumber::NewInlined( sum, scriptContext );
- }
- case TypeIds_Number:
- {
- double sum = JavascriptNumber::GetValue(aLeft) + JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::NewInlined( sum, scriptContext );
- }
- }
- break;
- }
- case TypeIds_String:
- {
- if( typeRight == TypeIds_String )
- {
- JavascriptString* leftString = JavascriptString::UnsafeFromVar(aLeft);
- JavascriptString* rightString = JavascriptString::UnsafeFromVar(aRight);
- return JavascriptString::Concat(leftString, rightString);
- }
- break;
- }
- }
- return Add_FullHelper_Wrapper(aLeft, aRight, scriptContext, nullptr, false);
- }
- #endif
- Var JavascriptMath::Add_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- Assert(aLeft != nullptr);
- Assert(aRight != nullptr);
- Assert(scriptContext != nullptr);
- Assert(result != nullptr);
- // If both sides are numbers, then we can do the addition directly, otherwise
- // we need to call the helper.
- if( TaggedInt::Is(aLeft) )
- {
- if( TaggedInt::Is(aRight) )
- {
- // Compute the sum using integer addition, then convert to double.
- // That way there's only one int->float conversion.
- #if INT32VAR
- int64 sum = TaggedInt::ToInt64(aLeft) + TaggedInt::ToInt64(aRight);
- #else
- int32 sum = TaggedInt::ToInt32(aLeft) + TaggedInt::ToInt32(aRight);
- #endif
- return JavascriptNumber::ToVarInPlace(sum, scriptContext, result);
- }
- else if( JavascriptNumber::Is_NoTaggedIntCheck(aRight) )
- {
- double sum = TaggedInt::ToDouble(aLeft) + JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::InPlaceNew( sum, scriptContext, result );
- }
- }
- else if( TaggedInt::Is(aRight) )
- {
- if( JavascriptNumber::Is_NoTaggedIntCheck(aLeft) )
- {
- double sum = JavascriptNumber::GetValue(aLeft) + TaggedInt::ToDouble(aRight);
- return JavascriptNumber::InPlaceNew( sum, scriptContext, result );
- }
- }
- else if( JavascriptNumber::Is_NoTaggedIntCheck(aLeft) && JavascriptNumber::Is_NoTaggedIntCheck(aRight) )
- {
- double sum = JavascriptNumber::GetValue(aLeft) + JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::InPlaceNew( sum, scriptContext, result );
- }
- return Add_FullHelper_Wrapper(aLeft, aRight, scriptContext, result, false);
- }
- Var JavascriptMath::AddLeftDead(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber *result)
- {
- if (JavascriptOperators::GetTypeId(aLeft) == TypeIds_String)
- {
- JavascriptString* leftString = JavascriptString::UnsafeFromVar(aLeft);
- JavascriptString* rightString;
- TypeId rightType = JavascriptOperators::GetTypeId(aRight);
- switch(rightType)
- {
- case TypeIds_String:
- rightString = JavascriptString::UnsafeFromVar(aRight);
- StringCommon:
- return leftString->ConcatDestructive(rightString);
- case TypeIds_Integer:
- rightString = scriptContext->GetIntegerString(aRight);
- goto StringCommon;
- case TypeIds_Number:
- rightString = JavascriptNumber::ToStringRadix10(JavascriptNumber::GetValue(aRight), scriptContext);
- goto StringCommon;
- }
- }
- if (TaggedInt::Is(aLeft))
- {
- if (TaggedInt::Is(aRight))
- {
- return TaggedInt::Add(aLeft, aRight, scriptContext);
- }
- else if (JavascriptNumber::Is_NoTaggedIntCheck(aRight))
- {
- return JavascriptNumber::ToVarMaybeInPlace(TaggedInt::ToDouble(aLeft) + JavascriptNumber::GetValue(aRight), scriptContext, result);
- }
- }
- else if (TaggedInt::Is(aRight))
- {
- if (JavascriptNumber::Is_NoTaggedIntCheck(aLeft))
- {
- return JavascriptNumber::ToVarMaybeInPlace(JavascriptNumber::GetValue(aLeft) + TaggedInt::ToDouble(aRight), scriptContext, result);
- }
- }
- else if (JavascriptNumber::Is_NoTaggedIntCheck(aLeft) && JavascriptNumber::Is_NoTaggedIntCheck(aRight))
- {
- return JavascriptNumber::ToVarMaybeInPlace(JavascriptNumber::GetValue(aLeft) + JavascriptNumber::GetValue(aRight), scriptContext, result);
- }
- return Add_FullHelper_Wrapper(aLeft, aRight, scriptContext, result, true);
- }
- Var JavascriptMath::Add_FullHelper_Wrapper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead)
- {
- Var aLeftToPrim = JavascriptConversion::ToPrimitive<JavascriptHint::None>(aLeft, scriptContext);
- Var aRightToPrim = JavascriptConversion::ToPrimitive<JavascriptHint::None>(aRight, scriptContext);
- return Add_FullHelper(aLeftToPrim, aRightToPrim, scriptContext, result, leftIsDead);
- }
- Var JavascriptMath::Add_FullHelper(Var primLeft, Var primRight, ScriptContext* scriptContext, JavascriptNumber *result, bool leftIsDead)
- {
- // If either side is a string, then the result is also a string
- if (JavascriptOperators::GetTypeId(primLeft) == TypeIds_String)
- {
- JavascriptString* stringLeft = JavascriptString::UnsafeFromVar(primLeft);
- JavascriptString* stringRight = nullptr;
- if (JavascriptOperators::GetTypeId(primRight) == TypeIds_String)
- {
- stringRight = JavascriptString::UnsafeFromVar(primRight);
- }
- else
- {
- stringRight = JavascriptConversion::ToString(primRight, scriptContext);
- }
- if(leftIsDead)
- {
- return stringLeft->ConcatDestructive(stringRight);
- }
- return JavascriptString::Concat(stringLeft, stringRight);
- }
- if (JavascriptOperators::GetTypeId(primRight) == TypeIds_String)
- {
- JavascriptString* stringLeft = JavascriptConversion::ToString(primLeft, scriptContext);
- JavascriptString* stringRight = JavascriptString::UnsafeFromVar(primRight);
- if(leftIsDead)
- {
- return stringLeft->ConcatDestructive(stringRight);
- }
- return JavascriptString::Concat(stringLeft, stringRight);
- }
- double sum = Add_Helper(primLeft, primRight, scriptContext);
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- Var JavascriptMath::MulAddLeft(Var mulLeft, Var mulRight, Var addLeft, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if(TaggedInt::Is(mulLeft))
- {
- if(TaggedInt::Is(mulRight))
- {
- // Compute the sum using integer addition, then convert to double.
- // That way there's only one int->float conversion.
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- Var mulResult = TaggedInt::MultiplyInPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Add_InPlace(addLeft, mulResult, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Add_Full(addLeft, mulResult, scriptContext);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = TaggedInt::ToDouble(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Add_DoubleHelper(addLeft, mulResult, scriptContext, result);
- }
- }
- else if(TaggedInt::Is(mulRight))
- {
- if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * TaggedInt::ToDouble(mulRight);
- return JavascriptMath::Add_DoubleHelper(addLeft, mulResult, scriptContext, result);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft) && JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Add_DoubleHelper(addLeft, mulResult, scriptContext, result);
- }
- Var aMul;
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- aMul = JavascriptMath::Multiply_InPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Add_InPlace(addLeft, aMul, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Add_Full(addLeft, aMul, scriptContext);
- }
- }
- Var JavascriptMath::MulAddRight(Var mulLeft, Var mulRight, Var addRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if(TaggedInt::Is(mulLeft))
- {
- if(TaggedInt::Is(mulRight))
- {
- // Compute the sum using integer addition, then convert to double.
- // That way there's only one int->float conversion.
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- Var mulResult = TaggedInt::MultiplyInPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Add_InPlace(mulResult, addRight, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Add_Full(mulResult, addRight, scriptContext);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = TaggedInt::ToDouble(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Add_DoubleHelper(mulResult, addRight, scriptContext, result);
- }
- }
- else if(TaggedInt::Is(mulRight))
- {
- if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * TaggedInt::ToDouble(mulRight);
- return JavascriptMath::Add_DoubleHelper(mulResult, addRight, scriptContext, result);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft) && JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Add_DoubleHelper(mulResult, addRight, scriptContext, result);
- }
- Var aMul;
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- aMul = JavascriptMath::Multiply_InPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Add_InPlace(aMul, addRight, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Add_Full(aMul, addRight, scriptContext);
- }
- }
- Var JavascriptMath::MulSubLeft(Var mulLeft, Var mulRight, Var subLeft, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if(TaggedInt::Is(mulLeft))
- {
- if(TaggedInt::Is(mulRight))
- {
- // Compute the sum using integer addition, then convert to double.
- // That way there's only one int->float conversion.
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- Var mulResult = TaggedInt::MultiplyInPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Subtract_InPlace(subLeft, mulResult, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Subtract_Full(subLeft, mulResult, scriptContext);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = TaggedInt::ToDouble(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Subtract_DoubleHelper(subLeft, mulResult, scriptContext, result);
- }
- }
- else if(TaggedInt::Is(mulRight))
- {
- if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * TaggedInt::ToDouble(mulRight);
- return JavascriptMath::Subtract_DoubleHelper(subLeft, mulResult, scriptContext, result);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft) && JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Subtract_DoubleHelper(subLeft, mulResult, scriptContext, result);
- }
- Var aMul;
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- aMul = JavascriptMath::Multiply_InPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Subtract_InPlace(subLeft, aMul, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Subtract_Full(subLeft, aMul, scriptContext);
- }
- }
- Var JavascriptMath::MulSubRight(Var mulLeft, Var mulRight, Var subRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if(TaggedInt::Is(mulLeft))
- {
- if(TaggedInt::Is(mulRight))
- {
- // Compute the sum using integer addition, then convert to double.
- // That way there's only one int->float conversion.
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- Var mulResult = TaggedInt::MultiplyInPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Subtract_InPlace(mulResult, subRight, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Subtract_Full(mulResult, subRight, scriptContext);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = TaggedInt::ToDouble(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Subtract_DoubleHelper(mulResult, subRight, scriptContext, result);
- }
- }
- else if(TaggedInt::Is(mulRight))
- {
- if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * TaggedInt::ToDouble(mulRight);
- return JavascriptMath::Subtract_DoubleHelper(mulResult, subRight, scriptContext, result);
- }
- }
- else if(JavascriptNumber::Is_NoTaggedIntCheck(mulLeft) && JavascriptNumber::Is_NoTaggedIntCheck(mulRight))
- {
- double mulResult = JavascriptNumber::GetValue(mulLeft) * JavascriptNumber::GetValue(mulRight);
- return JavascriptMath::Subtract_DoubleHelper(mulResult, subRight, scriptContext, result);
- }
- Var aMul;
- JavascriptNumber mulTemp(0, scriptContext->GetLibrary()->GetNumberTypeStatic());
- aMul = JavascriptMath::Multiply_InPlace(mulLeft, mulRight, scriptContext, &mulTemp);
- if (result)
- {
- return JavascriptMath::Subtract_InPlace(aMul, subRight, scriptContext, result);
- }
- else
- {
- return JavascriptMath::Subtract_Full(aMul, subRight, scriptContext);
- }
- }
- Var inline JavascriptMath::Add_DoubleHelper(double dblLeft, Var addRight, ScriptContext* scriptContext, JavascriptNumber*result)
- {
- if (TaggedInt::Is(addRight))
- {
- double sum = dblLeft + TaggedInt::ToDouble(addRight);
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else if (JavascriptNumber::Is_NoTaggedIntCheck(addRight))
- {
- double sum = dblLeft + JavascriptNumber::GetValue(addRight);
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else
- {
- Var aLeft = JavascriptNumber::ToVarMaybeInPlace(dblLeft, scriptContext, result);
- return Add_Full(aLeft, addRight, scriptContext);
- }
- }
- Var inline JavascriptMath::Add_DoubleHelper(Var addLeft, double dblRight, ScriptContext* scriptContext, JavascriptNumber*result)
- {
- if (TaggedInt::Is(addLeft))
- {
- double sum = TaggedInt::ToDouble(addLeft) + dblRight;
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else if (JavascriptNumber::Is_NoTaggedIntCheck(addLeft))
- {
- double sum = JavascriptNumber::GetValue(addLeft) + dblRight;
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else
- {
- Var aRight = JavascriptNumber::ToVarMaybeInPlace(dblRight, scriptContext, result);
- return Add_Full(addLeft, aRight, scriptContext);
- }
- }
- Var inline JavascriptMath::Subtract_DoubleHelper(double dblLeft, Var subRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if (TaggedInt::Is(subRight))
- {
- double sum = dblLeft - TaggedInt::ToDouble(subRight);
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else if (JavascriptNumber::Is_NoTaggedIntCheck(subRight))
- {
- double sum = dblLeft - JavascriptNumber::GetValue(subRight);
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else
- {
- Var aLeft = JavascriptNumber::ToVarMaybeInPlace(dblLeft, scriptContext, result);
- return Subtract_Full(aLeft, subRight, scriptContext);
- }
- }
- Var inline JavascriptMath::Subtract_DoubleHelper(Var subLeft, double dblRight, ScriptContext* scriptContext, JavascriptNumber*result)
- {
- if (TaggedInt::Is(subLeft))
- {
- double sum = TaggedInt::ToDouble(subLeft) - dblRight;
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else if (JavascriptNumber::Is_NoTaggedIntCheck(subLeft))
- {
- double sum = JavascriptNumber::GetValue(subLeft) - dblRight;
- return JavascriptNumber::ToVarMaybeInPlace(sum, scriptContext, result);
- }
- else
- {
- Var aRight = JavascriptNumber::ToVarMaybeInPlace(dblRight, scriptContext, result);
- return Subtract_Full(subLeft, aRight, scriptContext);
- }
- }
- Var JavascriptMath::Subtract_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- double difference = Subtract_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVarNoCheck(difference, scriptContext);
- }
- Var JavascriptMath::Subtract_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- double difference = Subtract_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(difference, scriptContext, result);
- }
- Var JavascriptMath::Divide_Full(Var aLeft,Var aRight, ScriptContext* scriptContext)
- {
- // If both arguments are TaggedInt, then try to do integer division
- // This case is not handled by the lowerer.
- if (TaggedInt::IsPair(aLeft, aRight))
- {
- return TaggedInt::Divide(aLeft, aRight, scriptContext);
- }
- return JavascriptNumber::NewInlined( Divide_Helper(aLeft, aRight, scriptContext), scriptContext );
- }
- Var JavascriptMath::Exponentiation_Full(Var aLeft, Var aRight, ScriptContext *scriptContext)
- {
- double x = JavascriptConversion::ToNumber(aLeft, scriptContext);
- double y = JavascriptConversion::ToNumber(aRight, scriptContext);
- return JavascriptNumber::ToVarNoCheck(Math::Pow(x, y), scriptContext);
- }
- Var JavascriptMath::Exponentiation_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
- double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
- double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(Math::Pow(dblLeft, dblRight), scriptContext, result);
- }
- Var JavascriptMath::Multiply_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- Assert(aLeft != nullptr);
- Assert(aRight != nullptr);
- Assert(scriptContext != nullptr);
- if(JavascriptNumber::Is(aLeft))
- {
- if(JavascriptNumber::Is(aRight))
- {
- double product = JavascriptNumber::GetValue(aLeft) * JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::ToVarNoCheck(product, scriptContext);
- }
- else if(TaggedInt::Is(aRight))
- {
- double product = TaggedInt::ToDouble(aRight) * JavascriptNumber::GetValue(aLeft);
- return JavascriptNumber::ToVarNoCheck(product, scriptContext);
- }
- }
- else if(JavascriptNumber::Is(aRight))
- {
- if(TaggedInt::Is(aLeft))
- {
- double product = TaggedInt::ToDouble(aLeft) * JavascriptNumber::GetValue(aRight);
- return JavascriptNumber::ToVarNoCheck(product, scriptContext);
- }
- }
- else if(TaggedInt::IsPair(aLeft, aRight))
- {
- return TaggedInt::Multiply(aLeft, aRight, scriptContext);
- }
- double product = Multiply_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVarNoCheck(product, scriptContext);
- }
- Var JavascriptMath::Multiply_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- if(JavascriptNumber::Is(aLeft))
- {
- if(JavascriptNumber::Is(aRight))
- {
- return JavascriptNumber::ToVarInPlace(
- JavascriptNumber::GetValue(aLeft) * JavascriptNumber::GetValue(aRight), scriptContext, result);
- }
- else if (TaggedInt::Is(aRight))
- {
- return JavascriptNumber::ToVarInPlace(
- JavascriptNumber::GetValue(aLeft) * TaggedInt::ToDouble(aRight), scriptContext, result);
- }
- }
- else if(JavascriptNumber::Is(aRight))
- {
- if(TaggedInt::Is(aLeft))
- {
- return JavascriptNumber::ToVarInPlace(
- TaggedInt::ToDouble(aLeft) * JavascriptNumber::GetValue(aRight), scriptContext, result);
- }
- }
- else if(TaggedInt::IsPair(aLeft, aRight))
- {
- return TaggedInt::MultiplyInPlace(aLeft, aRight, scriptContext, result);
- }
- double product = Multiply_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(product, scriptContext, result);
- }
- Var JavascriptMath::Divide_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- // If both arguments are TaggedInt, then try to do integer division
- // This case is not handled by the lowerer.
- if (TaggedInt::IsPair(aLeft, aRight))
- {
- return TaggedInt::DivideInPlace(aLeft, aRight, scriptContext, result);
- }
- double quotient = Divide_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(quotient, scriptContext, result);
- }
- Var JavascriptMath::Modulus_Full(Var aLeft, Var aRight, ScriptContext* scriptContext)
- {
- // If both arguments are TaggedInt, then try to do integer modulus.
- // This case is not handled by the lowerer.
- if (TaggedInt::IsPair(aLeft, aRight))
- {
- return TaggedInt::Modulus(aLeft, aRight, scriptContext);
- }
- double remainder = Modulus_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::ToVarNoCheck(remainder, scriptContext);
- }
- Var JavascriptMath::Modulus_InPlace(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result)
- {
- Assert(aLeft != nullptr);
- Assert(aRight != nullptr);
- Assert(scriptContext != nullptr);
- // If both arguments are TaggedInt, then try to do integer division
- // This case is not handled by the lowerer.
- if (TaggedInt::IsPair(aLeft, aRight))
- {
- return TaggedInt::Modulus(aLeft, aRight, scriptContext);
- }
- double remainder = Modulus_Helper(aLeft, aRight, scriptContext);
- return JavascriptNumber::InPlaceNew(remainder, scriptContext, result);
- }
- Var JavascriptMath::FinishOddDivByPow2(int32 value, ScriptContext *scriptContext)
- {
- return JavascriptNumber::New((double)(value + 0.5), scriptContext);
- }
- Var JavascriptMath::FinishOddDivByPow2_InPlace(int32 value, ScriptContext *scriptContext, JavascriptNumber* result)
- {
- return JavascriptNumber::InPlaceNew((double)(value + 0.5), scriptContext, result);
- }
- Var JavascriptMath::MaxInAnArray(RecyclableObject * function, CallInfo callInfo, ...)
- {
- PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
- ARGUMENTS(args, callInfo);
- Assert(args.Info.Count == 2);
- Var thisArg = args[0];
- Var arrayArg = args[1];
- ScriptContext * scriptContext = function->GetScriptContext();
- TypeId typeId = JavascriptOperators::GetTypeId(arrayArg);
- if (!JavascriptNativeArray::Is(typeId) && !(TypedArrayBase::Is(typeId) && typeId != TypeIds_CharArray && typeId != TypeIds_BoolArray))
- {
- if (JavascriptArray::IsVarArray(typeId) && JavascriptArray::UnsafeFromVar(arrayArg)->GetLength() == 0)
- {
- return scriptContext->GetLibrary()->GetNegativeInfinite();
- }
- return JavascriptFunction::CalloutHelper<false>(function, thisArg, /* overridingNewTarget = */nullptr, arrayArg, scriptContext);
- }
- if (JavascriptNativeArray::Is(typeId))
- {
- #if ENABLE_COPYONACCESS_ARRAY
- JavascriptLibrary::CheckAndConvertCopyOnAccessNativeIntArray<Var>(arrayArg);
- #endif
- JavascriptNativeArray * argsArray = JavascriptNativeArray::UnsafeFromVar(arrayArg);
- uint len = argsArray->GetLength();
- if (len == 0)
- {
- return scriptContext->GetLibrary()->GetNegativeInfinite();
- }
- if (argsArray->GetHead()->next != nullptr || !argsArray->HasNoMissingValues() ||
- argsArray->GetHead()->length != len)
- {
- return JavascriptFunction::CalloutHelper<false>(function, thisArg, /* overridingNewTarget = */nullptr, arrayArg, scriptContext);
- }
- return argsArray->FindMinOrMax(scriptContext, true /*findMax*/);
- }
- else
- {
- TypedArrayBase * argsArray = TypedArrayBase::UnsafeFromVar(arrayArg);
- uint len = argsArray->GetLength();
- if (len == 0)
- {
- return scriptContext->GetLibrary()->GetNegativeInfinite();
- }
- Var max = argsArray->FindMinOrMax(scriptContext, typeId, true /*findMax*/);
- if (max == nullptr)
- {
- return JavascriptFunction::CalloutHelper<false>(function, thisArg, /* overridingNewTarget = */nullptr, arrayArg, scriptContext);
- }
- return max;
- }
- }
- Var JavascriptMath::MinInAnArray(RecyclableObject * function, CallInfo callInfo, ...)
- {
- PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
- ARGUMENTS(args, callInfo);
- Assert(args.Info.Count == 2);
- Var thisArg = args[0];
- Var arrayArg = args[1];
- ScriptContext * scriptContext = function->GetScriptContext();
- TypeId typeId = JavascriptOperators::GetTypeId(arrayArg);
- if (!JavascriptNativeArray::Is(typeId) && !(TypedArrayBase::Is(typeId) && typeId != TypeIds_CharArray && typeId != TypeIds_BoolArray))
- {
- if (JavascriptArray::Is(typeId) && JavascriptArray::UnsafeFromVar(arrayArg)->GetLength() == 0)
- {
- return scriptContext->GetLibrary()->GetPositiveInfinite();
- }
- return JavascriptFunction::CalloutHelper<false>(function, thisArg, /* overridingNewTarget = */nullptr, arrayArg, scriptContext);
- }
- if (JavascriptNativeArray::Is(typeId))
- {
- #if ENABLE_COPYONACCESS_ARRAY
- JavascriptLibrary::CheckAndConvertCopyOnAccessNativeIntArray<Var>(arrayArg);
- #endif
- JavascriptNativeArray * argsArray = JavascriptNativeArray::UnsafeFromVar(arrayArg);
- uint len = argsArray->GetLength();
- if (len == 0)
- {
- return scriptContext->GetLibrary()->GetPositiveInfinite();
- }
- if (argsArray->GetHead()->next != nullptr || !argsArray->HasNoMissingValues() ||
- argsArray->GetHead()->length != len)
- {
- return JavascriptFunction::CalloutHelper<false>(function, thisArg, /* overridingNewTarget = */nullptr, arrayArg, scriptContext);
- }
- return argsArray->FindMinOrMax(scriptContext, false /*findMax*/);
- }
- else
- {
- TypedArrayBase * argsArray = TypedArrayBase::UnsafeFromVar(arrayArg);
- uint len = argsArray->GetLength();
- if (len == 0)
- {
- return scriptContext->GetLibrary()->GetPositiveInfinite();
- }
- Var min = argsArray->FindMinOrMax(scriptContext, typeId, false /*findMax*/);
- if (min == nullptr)
- {
- return JavascriptFunction::CalloutHelper<false>(function, thisArg, /* overridingNewTarget = */nullptr, arrayArg, scriptContext);
- }
- return min;
- }
- }
- void InitializeRandomSeeds(uint64 *seed0, uint64 *seed1, ScriptContext *scriptContext)
- {
- #if DBG
- if (CONFIG_FLAG(PRNGSeed0) && CONFIG_FLAG(PRNGSeed1))
- {
- *seed0 = CONFIG_FLAG(PRNGSeed0);
- *seed1 = CONFIG_FLAG(PRNGSeed1);
- }
- else
- #endif
- {
- LARGE_INTEGER s0;
- LARGE_INTEGER s1;
- if (!rand_s(reinterpret_cast<unsigned int*>(&s0.LowPart)) &&
- !rand_s(reinterpret_cast<unsigned int*>(&s0.HighPart)) &&
- !rand_s(reinterpret_cast<unsigned int*>(&s1.LowPart)) &&
- !rand_s(reinterpret_cast<unsigned int*>(&s1.HighPart)))
- {
- *seed0 = s0.QuadPart;
- *seed1 = s1.QuadPart;
- }
- else
- {
- AssertMsg(false, "Unable to initialize PRNG seeds with rand_s. Revert to using entropy.");
- #ifdef ENABLE_CUSTOM_ENTROPY
- ThreadContext *threadContext = scriptContext->GetThreadContext();
- threadContext->GetEntropy().AddThreadCycleTime();
- threadContext->GetEntropy().AddIoCounters();
- *seed0 = threadContext->GetEntropy().GetRand();
- threadContext->GetEntropy().AddThreadCycleTime();
- threadContext->GetEntropy().AddIoCounters();
- *seed1 = threadContext->GetEntropy().GetRand();
- #endif
- }
- }
- }
- double ConvertRandomSeedsToDouble(const uint64 seed0, const uint64 seed1)
- {
- const uint64 mExp = 0x3FF0000000000000;
- const uint64 mMant = 0x000FFFFFFFFFFFFF;
- // Take lower 52 bits of the sum of two seeds to make a double
- // Subtract 1.0 to negate the implicit integer bit of 1. Final range: [0.0, 1.0)
- // See IEEE754 Double-precision floating-point format for details
- // https://en.wikipedia.org/wiki/Double-precision_floating-point_format
- uint64 resplusone_ui64 = ((seed0 + seed1) & mMant) | mExp;
- double res = *(reinterpret_cast<double*>(&resplusone_ui64)) - 1.0;
- return res;
- }
- void Xorshift128plus(uint64 *seed0, uint64 *seed1)
- {
- uint64 s1 = *seed0;
- uint64 s0 = *seed1;
- *seed0 = s0;
- s1 ^= s1 << 23;
- s1 ^= s1 >> 17;
- s1 ^= s0;
- s1 ^= s0 >> 26;
- *seed1 = s1;
- }
- double JavascriptMath::Random(ScriptContext *scriptContext)
- {
- uint64 seed0;
- uint64 seed1;
- if (!scriptContext->GetLibrary()->IsPRNGSeeded())
- {
- InitializeRandomSeeds(&seed0, &seed1, scriptContext);
- #if DBG_DUMP
- OUTPUT_TRACE(Js::PRNGPhase, _u("[PRNG:%x] INIT %I64x %I64x\n"), scriptContext, seed0, seed1);
- #endif
- scriptContext->GetLibrary()->SetIsPRNGSeeded(true);
- #if ENABLE_TTD
- if(scriptContext->ShouldPerformReplayAction())
- {
- scriptContext->GetThreadContext()->TTDLog->ReplayExternalEntropyRandomEvent(&seed0, &seed1);
- }
- else if(scriptContext->ShouldPerformRecordAction())
- {
- scriptContext->GetThreadContext()->TTDLog->RecordExternalEntropyRandomEvent(seed0, seed1);
- }
- else
- {
- ;
- }
- #endif
- }
- else
- {
- seed0 = scriptContext->GetLibrary()->GetRandSeed0();
- seed1 = scriptContext->GetLibrary()->GetRandSeed1();
- }
- #if DBG_DUMP
- OUTPUT_TRACE(Js::PRNGPhase, _u("[PRNG:%x] SEED %I64x %I64x\n"), scriptContext, seed0, seed1);
- #endif
- Xorshift128plus(&seed0, &seed1);
- //update the seeds in script context
- scriptContext->GetLibrary()->SetRandSeed0(seed0);
- scriptContext->GetLibrary()->SetRandSeed1(seed1);
- double res = ConvertRandomSeedsToDouble(seed0, seed1);
- #if DBG_DUMP
- OUTPUT_TRACE(Js::PRNGPhase, _u("[PRNG:%x] RAND %I64x\n"), scriptContext, *((uint64 *)&res));
- #endif
- return res;
- }
- uint32 JavascriptMath::ToUInt32(double T1)
- {
- // Same as doing ToInt32 and reinterpret the bits as uint32
- return (uint32)ToInt32Core(T1);
- }
- int32 JavascriptMath::ToInt32(double T1)
- {
- return JavascriptMath::ToInt32Core(T1);
- }
- int32 JavascriptMath::ToInt32_Full(Var aValue, ScriptContext* scriptContext)
- {
- AssertMsg(!TaggedInt::Is(aValue), "Should be detected");
- // This is used when TaggedInt's overflow but remain under int32
- // so Number is our most critical case:
- TypeId typeId = JavascriptOperators::GetTypeId(aValue);
- if (typeId == TypeIds_Number)
- {
- return JavascriptMath::ToInt32Core(JavascriptNumber::GetValue(aValue));
- }
- return JavascriptConversion::ToInt32_Full(aValue, scriptContext);
- }
- }
|