mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 12:10:47 +00:00
!2177 optimization math and number function
Merge pull request !2177 from 李_文强/master
This commit is contained in:
commit
d347e9b87f
@ -20,6 +20,7 @@
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ecmascript/base/builtins_base.h"
|
||||
#include "ecmascript/base/string_helper.h"
|
||||
@ -28,7 +29,7 @@
|
||||
|
||||
namespace panda::ecmascript::base {
|
||||
enum class Sign { NONE, NEG, POS };
|
||||
|
||||
uint64_t* RandomGenerator::randomState {nullptr};
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define RETURN_IF_CONVERSION_END(p, end, result) \
|
||||
if ((p) == (end)) { \
|
||||
@ -793,4 +794,27 @@ int NumberHelper::GetMinmumDigits(double d, int *decpt, char *buf)
|
||||
|
||||
return digits;
|
||||
}
|
||||
uint64_t* RandomGenerator::GetRandomState()
|
||||
{
|
||||
return randomState;
|
||||
}
|
||||
uint64_t RandomGenerator::XorShift64(uint64_t *pVal)
|
||||
{
|
||||
uint64_t x = *pVal;
|
||||
x ^= x >> RIGHT12;
|
||||
x ^= x << LEFT25;
|
||||
x ^= x >> RIGHT27;
|
||||
*pVal = x;
|
||||
return x * GET_MULTIPLY;
|
||||
}
|
||||
void RandomGenerator::InitRandom()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
auto val = static_cast<int64_t>((tv.tv_sec * SECONDS_TO_SUBTLE) + tv.tv_usec);
|
||||
randomState = reinterpret_cast<uint64_t *>(&val);
|
||||
// the state must be non zero
|
||||
if (*randomState == 0)
|
||||
*randomState = 1;
|
||||
}
|
||||
} // namespace panda::ecmascript::base
|
||||
|
@ -62,6 +62,15 @@ static constexpr size_t INT16_BITS = 16;
|
||||
static constexpr size_t INT8_BITS = 8;
|
||||
static constexpr size_t JS_DTOA_BUF_SIZE = 128;
|
||||
|
||||
// help defines for random
|
||||
static constexpr int LEFT52 = 52 ;
|
||||
static constexpr int RIGHT12 = 12;
|
||||
static constexpr uint32_t USE_LEFT = 0x3ff;
|
||||
static constexpr int SECONDS_TO_SUBTLE = 1000000;
|
||||
static constexpr int RIGHT27 = 27;
|
||||
static constexpr int LEFT25 = 25;
|
||||
static constexpr uint64_t GET_MULTIPLY = 0x2545F4914F6CDD1D;
|
||||
|
||||
class NumberHelper {
|
||||
public:
|
||||
static inline JSTaggedType GetNaN()
|
||||
@ -105,5 +114,13 @@ private:
|
||||
static void GetBase(double d, int digits, int *decpt, char *buf, char *bufTmp, int size);
|
||||
static int GetMinmumDigits(double d, int *decpt, char *buf);
|
||||
};
|
||||
class RandomGenerator {
|
||||
public:
|
||||
static uint64_t* GetRandomState();
|
||||
static uint64_t XorShift64(uint64_t *pVal);
|
||||
static void InitRandom();
|
||||
private:
|
||||
static uint64_t* randomState;
|
||||
};
|
||||
} // namespace panda::ecmascript::base
|
||||
#endif // ECMASCRIPT_BASE_NUMBER_HELPER_H
|
||||
|
@ -162,6 +162,7 @@ using Promise = builtins::BuiltinsPromise;
|
||||
using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler;
|
||||
using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob;
|
||||
using ErrorType = base::ErrorType;
|
||||
using RandomGenerator = base::RandomGenerator;
|
||||
using DataView = builtins::BuiltinsDataView;
|
||||
using Intl = builtins::BuiltinsIntl;
|
||||
using Locale = builtins::BuiltinsLocale;
|
||||
@ -1477,6 +1478,7 @@ void Builtins::InitializeMath(const JSHandle<GlobalEnv> &env, const JSHandle<JST
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSHClass> mathDynclass = factory_->NewEcmaDynClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
|
||||
JSHandle<JSObject> mathObject = factory_->NewJSObjectWithInit(mathDynclass);
|
||||
RandomGenerator::InitRandom();
|
||||
SetFunction(env, mathObject, "abs", Math::Abs, FunctionLength::ONE);
|
||||
SetFunction(env, mathObject, "acos", Math::Acos, FunctionLength::ONE);
|
||||
SetFunction(env, mathObject, "acosh", Math::Acosh, FunctionLength::ONE);
|
||||
|
@ -14,14 +14,16 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/builtins/builtins_math.h"
|
||||
|
||||
#include <random>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ecmascript/ecma_runtime_call_info.h"
|
||||
#include "ecmascript/js_tagged_number.h"
|
||||
#include "utils/bit_utils.h"
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
using NumberHelper = base::NumberHelper;
|
||||
using RandomGenerator = base::RandomGenerator;
|
||||
|
||||
// 20.2.2.1
|
||||
JSTaggedValue BuiltinsMath::Abs(EcmaRuntimeCallInfo *argv)
|
||||
@ -583,13 +585,15 @@ JSTaggedValue BuiltinsMath::Pow(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue BuiltinsMath::Random([[maybe_unused]] EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Math, Random);
|
||||
std::random_device rd;
|
||||
std::default_random_engine engine(rd());
|
||||
std::uniform_real_distribution<double> dis(0, std::random_device::max() - 1);
|
||||
// result range [0,1)
|
||||
double result = dis(engine) / std::random_device::max();
|
||||
return GetTaggedDouble(result);
|
||||
JSThread *thread = argv->GetThread();
|
||||
BUILTINS_API_TRACE(thread, Math, Random);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
Float64Union dataU;
|
||||
uint64_t val;
|
||||
uint64_t* randomState = RandomGenerator::GetRandomState();
|
||||
val = RandomGenerator::XorShift64(randomState);
|
||||
dataU.u64 = ((uint64_t)base::USE_LEFT << base::LEFT52) | (val >> base::RIGHT12);
|
||||
return GetTaggedDouble(dataU.d - 1.0);
|
||||
}
|
||||
|
||||
// 20.2.2.28
|
||||
|
@ -19,6 +19,10 @@
|
||||
#include "ecmascript/base/builtins_base.h"
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
union Float64Union {
|
||||
double d;
|
||||
uint64_t u64;
|
||||
};
|
||||
class BuiltinsMath : public base::BuiltinsBase {
|
||||
public:
|
||||
// 20.2.1.1
|
||||
|
@ -218,11 +218,11 @@ JSTaggedValue BuiltinsNumber::ParseInt(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue BuiltinsNumber::ToExponential(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Number, ToExponential);
|
||||
JSThread *thread = argv->GetThread();
|
||||
BUILTINS_API_TRACE(thread, Number, ToExponential);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedNumber value = ThisNumberValue(argv);
|
||||
JSTaggedNumber value = ThisNumberValue(thread, argv);
|
||||
// 2. ReturnIfAbrupt(x).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
@ -266,11 +266,11 @@ JSTaggedValue BuiltinsNumber::ToExponential(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue BuiltinsNumber::ToFixed(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Number, ToFixed);
|
||||
JSThread *thread = argv->GetThread();
|
||||
BUILTINS_API_TRACE(thread, Number, ToFixed);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedNumber value = ThisNumberValue(argv);
|
||||
JSTaggedNumber value = ThisNumberValue(thread, argv);
|
||||
// 2. ReturnIfAbrupt(x).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 3. Let f be ToInteger(fractionDigits). (If fractionDigits is undefined, this step produces the value 0).
|
||||
@ -290,7 +290,8 @@ JSTaggedValue BuiltinsNumber::ToFixed(EcmaRuntimeCallInfo *argv)
|
||||
// 6. If x is NaN, return the String "NaN".
|
||||
double valueNumber = value.GetNumber();
|
||||
if (std::isnan(valueNumber)) {
|
||||
return GetTaggedString(thread, "NaN");
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
return globalConst->GetNanCapitalString();
|
||||
}
|
||||
// 9. If x 1021, then
|
||||
// a. Let m = ToString(x).
|
||||
@ -310,7 +311,7 @@ JSTaggedValue BuiltinsNumber::ToLocaleString(EcmaRuntimeCallInfo *argv)
|
||||
BUILTINS_API_TRACE(thread, Number, ToLocaleString);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedNumber x = ThisNumberValue(argv);
|
||||
JSTaggedNumber x = ThisNumberValue(thread, argv);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »).
|
||||
JSHandle<JSFunction> ctor(thread->GetEcmaVM()->GetGlobalEnv()->GetNumberFormatFunction());
|
||||
@ -332,11 +333,11 @@ JSTaggedValue BuiltinsNumber::ToLocaleString(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue BuiltinsNumber::ToPrecision(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Number, ToPrecision);
|
||||
JSThread *thread = argv->GetThread();
|
||||
BUILTINS_API_TRACE(thread, Number, ToPrecision);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedNumber value = ThisNumberValue(argv);
|
||||
JSTaggedNumber value = ThisNumberValue(thread, argv);
|
||||
// 2. ReturnIfAbrupt(x).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
@ -376,11 +377,11 @@ JSTaggedValue BuiltinsNumber::ToPrecision(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue BuiltinsNumber::ToString(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Number, ToString);
|
||||
JSThread *thread = argv->GetThread();
|
||||
BUILTINS_API_TRACE(thread, Number, ToString);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedNumber value = ThisNumberValue(argv);
|
||||
JSTaggedNumber value = ThisNumberValue(thread, argv);
|
||||
// 2. ReturnIfAbrupt(x).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
@ -425,17 +426,18 @@ JSTaggedValue BuiltinsNumber::ToString(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue BuiltinsNumber::ValueOf(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Number, ValueOf);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedValue x = ThisNumberValue(argv);
|
||||
JSThread *thread = argv->GetThread();
|
||||
BUILTINS_API_TRACE(thread, Number, ValueOf);
|
||||
// 1. Let x be ? thisNumberValue(this value).
|
||||
JSTaggedValue x = ThisNumberValue(thread, argv);
|
||||
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return x;
|
||||
}
|
||||
|
||||
JSTaggedNumber BuiltinsNumber::ThisNumberValue(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedNumber BuiltinsNumber::ThisNumberValue(JSThread *thread, EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Number, ThisNumberValue);
|
||||
BUILTINS_API_TRACE(thread, Number, ThisNumberValue);
|
||||
JSHandle<JSTaggedValue> value = GetThis(argv);
|
||||
if (value->IsNumber()) {
|
||||
return JSTaggedNumber(value.GetTaggedValue());
|
||||
@ -446,7 +448,6 @@ JSTaggedNumber BuiltinsNumber::ThisNumberValue(EcmaRuntimeCallInfo *argv)
|
||||
return JSTaggedNumber(primitive);
|
||||
}
|
||||
}
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "not number type", JSTaggedNumber::Exception());
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
static JSTaggedValue ValueOf(EcmaRuntimeCallInfo *argv);
|
||||
|
||||
private:
|
||||
static JSTaggedNumber ThisNumberValue(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedNumber ThisNumberValue(JSThread *thread, EcmaRuntimeCallInfo *argv);
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
#endif // ECMASCRIPT_BUILTINS_BUILTINS_NUBMER_H
|
||||
|
@ -435,6 +435,7 @@ public:
|
||||
const JSHandle<JSTaggedValue> &newTarget);
|
||||
JSHandle<JSObject> NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor);
|
||||
void InitializeJSObject(const JSHandle<JSObject> &obj, const JSHandle<JSHClass> &jshclass);
|
||||
|
||||
JSHandle<JSObject> NewJSObjectWithInit(const JSHandle<JSHClass> &jshclass);
|
||||
uintptr_t NewSpaceBySnapshotAllocator(size_t size);
|
||||
JSHandle<MachineCode> NewMachineCodeObject(size_t length, const uint8_t *data);
|
||||
|
Loading…
Reference in New Issue
Block a user