Merge remote-tracking branch 'openharmony/master' into dev_shareheap

Change-Id: Ic0261b902b4c6ce2105ea5369f7129371aec6910
This commit is contained in:
wengchangcheng 2024-03-16 10:02:20 +08:00
commit 57301d1c3a
111 changed files with 3891 additions and 645 deletions

View File

@ -637,8 +637,8 @@ bool JsonStringifier::SerializeElements(const JSHandle<JSObject> &obj, const JSH
return hasContent;
}
void JsonStringifier::PrintAddrandValue(JSTaggedValue enumCache, const JSHandle<JSHClass> &jsHclass,
const JSHandle<JSObject> &obj)
bool JsonStringifier::SerializeKeys(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &replacer,
bool hasContent)
{
enum ServType : uint8_t {
Num_Zero,
@ -653,7 +653,12 @@ void JsonStringifier::PrintAddrandValue(JSTaggedValue enumCache, const JSHandle<
Num_Nine,
Num_Ten
};
if (enumCache.GetRawData() > 0x1000000000000000) {
JSHandle<TaggedArray> propertiesArr(thread_, obj->GetProperties());
if (!propertiesArr->IsDictionaryMode()) {
bool hasChangedToDictionaryMode = false;
JSHandle<JSHClass> jsHclass(thread_, obj->GetJSHClass());
JSTaggedValue enumCache = jsHclass->GetEnumCache();
if (enumCache.GetRawData() > 0x1000000000000000) {
LOG_DEBUGGER(FATAL) << "[wxj]JsonStringifier::SerializeKeys, jsHclass addr = " << *jsHclass
<< ", [wxj] obj addr:" << *obj
<< ", [wxj] Type = " << JSHClass::DumpJSType(jsHclass->GetObjectType())
@ -680,54 +685,17 @@ void JsonStringifier::PrintAddrandValue(JSTaggedValue enumCache, const JSHandle<
<< ", [wxj] after9:" << *(reinterpret_cast<void **>(*jsHclass) + ServType::Num_Nine)
<< ", [wxj] after10:" << *(reinterpret_cast<void **>(*jsHclass) + ServType::Num_Ten);
}
}
bool JsonStringifier::SerializeKeysFromEnumCache(JSTaggedValue enumCache, const JSHandle<JSHClass> &jsHclass,
const JSHandle<JSObject> &obj, const JSHandle<TaggedArray> &propertiesArr,
const JSHandle<JSTaggedValue> &replacer, bool hasContent)
{
JSHandle<TaggedArray> cache(thread_, enumCache);
uint32_t length = cache->GetLength();
for (uint32_t i = 0; i < length; i++) {
JSTaggedValue key = cache->Get(i);
if (!key.IsString()) {
continue;
}
handleKey_.Update(key);
JSTaggedValue value;
LayoutInfo *layoutInfo = LayoutInfo::Cast(jsHclass->GetLayout().GetTaggedObject());
int index = JSHClass::FindPropertyEntry(thread_, *jsHclass, key);
PropertyAttributes attr(layoutInfo->GetAttr(index));
ASSERT(static_cast<int>(attr.GetOffset()) == index);
value = attr.IsInlinedProps()
? obj->GetPropertyInlinedPropsWithRep(static_cast<uint32_t>(index), attr)
: propertiesArr->Get(static_cast<uint32_t>(index) - jsHclass->GetInlinedProperties());
if (attr.IsInlinedProps() && value.IsHole()) {
continue;
}
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
return hasContent;
}
bool JsonStringifier::SerializeKeysFromProperties(int end, bool hasChangedToDictionaryMode, JSHandle<JSHClass> &jsHclass,
const JSHandle<JSObject> &obj, JSHandle<TaggedArray> &propertiesArr,
const JSHandle<JSTaggedValue> &replacer, bool hasContent)
{
for (int i = 0; i < end; i++) {
LayoutInfo *layoutInfo = LayoutInfo::Cast(jsHclass->GetLayout().GetTaggedObject());
JSTaggedValue key = layoutInfo->GetKey(i);
if (!hasChangedToDictionaryMode) {
if (key.IsString() && layoutInfo->GetAttr(i).IsEnumerable()) {
if (JSObject::GetEnumCacheKind(thread_, enumCache) == EnumCacheKind::ONLY_OWN_KEYS) {
JSHandle<TaggedArray> cache(thread_, enumCache);
uint32_t length = cache->GetLength();
for (uint32_t i = 0; i < length; i++) {
JSTaggedValue key = cache->Get(i);
if (!key.IsString()) {
continue;
}
handleKey_.Update(key);
JSTaggedValue value;
LayoutInfo *layoutInfo = LayoutInfo::Cast(jsHclass->GetLayout().GetTaggedObject());
int index = JSHClass::FindPropertyEntry(thread_, *jsHclass, key);
PropertyAttributes attr(layoutInfo->GetAttr(index));
ASSERT(static_cast<int>(attr.GetOffset()) == index);
@ -739,85 +707,110 @@ bool JsonStringifier::SerializeKeysFromProperties(int end, bool hasChangedToDict
}
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
JSHandle<JSTaggedValue>(obj));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
if (obj->GetProperties().IsDictionary()) {
hasChangedToDictionaryMode = true;
propertiesArr = JSHandle<TaggedArray>(thread_, obj->GetProperties());
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
return hasContent;
}
int end = static_cast<int>(jsHclass->NumberOfProps());
if (end <= 0) {
return hasContent;
}
for (int i = 0; i < end; i++) {
LayoutInfo *layoutInfo = LayoutInfo::Cast(jsHclass->GetLayout().GetTaggedObject());
JSTaggedValue key = layoutInfo->GetKey(i);
if (!hasChangedToDictionaryMode) {
if (key.IsString() && layoutInfo->GetAttr(i).IsEnumerable()) {
handleKey_.Update(key);
JSTaggedValue value;
int index = JSHClass::FindPropertyEntry(thread_, *jsHclass, key);
PropertyAttributes attr(layoutInfo->GetAttr(index));
ASSERT(static_cast<int>(attr.GetOffset()) == index);
value = attr.IsInlinedProps()
? obj->GetPropertyInlinedPropsWithRep(static_cast<uint32_t>(index), attr)
: propertiesArr->Get(static_cast<uint32_t>(index) - jsHclass->GetInlinedProperties());
if (attr.IsInlinedProps() && value.IsHole()) {
continue;
}
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
if (obj->GetProperties().IsDictionary()) {
hasChangedToDictionaryMode = true;
propertiesArr = JSHandle<TaggedArray>(thread_, obj->GetProperties());
}
jsHclass = JSHandle<JSHClass>(thread_, obj->GetJSHClass());
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
jsHclass = JSHandle<JSHClass>(thread_, obj->GetJSHClass());
} else {
JSHandle<NameDictionary> nameDic(propertiesArr);
int index = nameDic->FindEntry(key);
if (!key.IsString()) {
continue;
}
PropertyAttributes attr = nameDic->GetAttributes(index);
if (!attr.IsEnumerable() || index < 0) {
continue;
}
JSTaggedValue value = nameDic->GetValue(index);
handleKey_.Update(key);
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
jsHclass = JSHandle<JSHClass>(thread_, obj->GetJSHClass());
}
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
}
return hasContent;
}
if (obj->IsJSGlobalObject()) {
JSHandle<GlobalDictionary> globalDic(propertiesArr);
int size = globalDic->Size();
CVector<std::pair<JSHandle<JSTaggedValue>, PropertyAttributes>> sortArr;
for (int hashIndex = 0; hashIndex < size; hashIndex++) {
JSTaggedValue key = globalDic->GetKey(hashIndex);
if (!key.IsString()) {
continue;
}
PropertyAttributes attr = globalDic->GetAttributes(hashIndex);
if (!attr.IsEnumerable()) {
continue;
}
std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> pair(JSHandle<JSTaggedValue>(thread_, key), attr);
sortArr.emplace_back(pair);
}
std::sort(sortArr.begin(), sortArr.end(), JsonHelper::CompareKey);
for (const auto &entry : sortArr) {
JSTaggedValue entryKey = entry.first.GetTaggedValue();
handleKey_.Update(entryKey);
int index = globalDic->FindEntry(entryKey);
if (index == -1) {
continue;
}
JSTaggedValue value = globalDic->GetValue(index);
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
} else {
JSHandle<NameDictionary> nameDic(propertiesArr);
int index = nameDic->FindEntry(key);
if (!key.IsString()) {
continue;
}
PropertyAttributes attr = nameDic->GetAttributes(index);
if (!attr.IsEnumerable() || index < 0) {
continue;
}
JSTaggedValue value = nameDic->GetValue(index);
handleKey_.Update(key);
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
jsHclass = JSHandle<JSHClass>(thread_, obj->GetJSHClass());
}
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
}
return hasContent;
}
bool JsonStringifier::SerializeKeysFromGlobalObjects(const JSHandle<TaggedArray> &propertiesArr, const JSHandle<JSObject> &obj,
const JSHandle<JSTaggedValue> &replacer, bool hasContent)
{
JSHandle<GlobalDictionary> globalDic(propertiesArr);
int size = globalDic->Size();
CVector<std::pair<JSHandle<JSTaggedValue>, PropertyAttributes>> sortArr;
for (int hashIndex = 0; hashIndex < size; hashIndex++) {
JSTaggedValue key = globalDic->GetKey(hashIndex);
if (!key.IsString()) {
continue;
}
PropertyAttributes attr = globalDic->GetAttributes(hashIndex);
if (!attr.IsEnumerable()) {
continue;
}
std::pair<JSHandle<JSTaggedValue>, PropertyAttributes> pair(JSHandle<JSTaggedValue>(thread_, key), attr);
sortArr.emplace_back(pair);
}
std::sort(sortArr.begin(), sortArr.end(), JsonHelper::CompareKey);
for (const auto &entry : sortArr) {
JSTaggedValue entryKey = entry.first.GetTaggedValue();
handleKey_.Update(entryKey);
int index = globalDic->FindEntry(entryKey);
if (index == -1) {
continue;
}
JSTaggedValue value = globalDic->GetValue(index);
if (UNLIKELY(value.IsAccessor())) {
value = JSObject::CallGetter(thread_, AccessorData::Cast(value.GetTaggedObject()),
JSHandle<JSTaggedValue>(obj));
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
}
handleValue_.Update(value);
hasContent = JsonStringifier::AppendJsonString(obj, replacer, hasContent);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false);
return hasContent;
}
return hasContent;
}
bool JsonStringifier::SerializeKeysFromNameDic(const JSHandle<TaggedArray> &propertiesArr, const JSHandle<JSObject> &obj,
const JSHandle<JSTaggedValue> &replacer, bool hasContent)
{
JSHandle<NameDictionary> nameDic(propertiesArr);
int size = nameDic->Size();
CVector<std::pair<JSHandle<JSTaggedValue>, PropertyAttributes>> sortArr;
@ -853,30 +846,6 @@ bool JsonStringifier::SerializeKeysFromNameDic(const JSHandle<TaggedArray> &prop
}
return hasContent;
}
bool JsonStringifier::SerializeKeys(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &replacer,
bool hasContent)
{
JSHandle<TaggedArray> propertiesArr(thread_, obj->GetProperties());
if (!propertiesArr->IsDictionaryMode()) {
bool hasChangedToDictionaryMode = false;
JSHandle<JSHClass> jsHclass(thread_, obj->GetJSHClass());
JSTaggedValue enumCache = jsHclass->GetEnumCache();
PrintAddrandValue(enumCache, jsHclass, obj);
if (JSObject::GetEnumCacheKind(thread_, enumCache) == EnumCacheKind::ONLY_OWN_KEYS) {
return SerializeKeysFromEnumCache(enumCache, jsHclass, obj, propertiesArr, replacer, hasContent);
}
int end = static_cast<int>(jsHclass->NumberOfProps());
if (end <= 0) {
return hasContent;
}
return SerializeKeysFromProperties(end, hasChangedToDictionaryMode, jsHclass, obj, propertiesArr, replacer, hasContent);
}
if (obj->IsJSGlobalObject()) {
return SerializeKeysFromGlobalObjects(propertiesArr, obj, replacer, hasContent);
}
hasContent = SerializeKeysFromNameDic(propertiesArr, obj, replacer, hasContent);
return hasContent;
}
bool JsonStringifier::AppendJsonString(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &replacer,
bool hasContent)

View File

@ -64,17 +64,6 @@ private:
bool CalculateStringGap(const JSHandle<EcmaString> &primString);
bool AppendJsonString(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &replacer, bool hasContent);
bool SerializeElements(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &replacer, bool hasContent);
void PrintAddrandValue(JSTaggedValue enumCache, const JSHandle<JSHClass> &jsHclass, const JSHandle<JSObject> &obj);
bool SerializeKeysFromEnumCache(JSTaggedValue enumCache, const JSHandle<JSHClass> &jsHclass, const JSHandle<JSObject> &obj,
const JSHandle<TaggedArray> &propertiesArr, const JSHandle<JSTaggedValue> &replacer,
bool hasContent);
bool SerializeKeysFromProperties(int end, bool hasChangedToDictionaryMode, JSHandle<JSHClass> &jsHclass,
const JSHandle<JSObject> &obj, JSHandle<TaggedArray> &propertiesArr,
const JSHandle<JSTaggedValue> &replacer, bool hasContent);
bool SerializeKeysFromGlobalObjects(const JSHandle<TaggedArray> &propertiesArr, const JSHandle<JSObject> &obj,
const JSHandle<JSTaggedValue> &replacer, bool hasContent);
bool SerializeKeysFromNameDic(const JSHandle<TaggedArray> &propertiesArr, const JSHandle<JSObject> &obj,
const JSHandle<JSTaggedValue> &replacer, bool hasContent);
bool SerializeKeys(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &replacer, bool hasContent);
CString gap_;

View File

@ -41,7 +41,11 @@ JSTaggedValue BuiltinsMath::Abs(EcmaRuntimeCallInfo *argv)
return GetTaggedDouble(std::fabs(numberValue.GetDouble()));
}
// if number_value is int,boolean,null, deal in this case
return GetTaggedInt(std::abs(numberValue.GetInt()));
int value = numberValue.GetInt();
if (value == INT_MIN) {
return GetTaggedDouble(-static_cast<int64_t>(INT_MIN));
}
return GetTaggedInt(std::abs(value));
}
// 20.2.2.2

View File

@ -34,40 +34,40 @@
// where BuiltinsMath::func refers to the native implementation of Math[name].
// kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
#define BUILTIN_MATH_FUNCTIONS(V) \
V("abs", Abs, 1, ABS) /* Math.abs ( x ) */ \
V("acos", Acos, 1, ACOS) /* Math.acos ( x ) */ \
V("acosh", Acosh, 1, INVALID) /* Math.acosh ( x ) */ \
V("asin", Asin, 1, INVALID) /* Math.asin ( x ) */ \
V("asinh", Asinh, 1, INVALID) /* Math.asinh ( x ) */ \
V("atan", Atan, 1, ATAN) /* Math.atan ( x ) */ \
V("atan2", Atan2, 2, INVALID) /* Math.atan2 ( y, x ) */ \
V("atanh", Atanh, 1, INVALID) /* Math.atanh ( x ) */ \
V("abs", Abs, 1, MathAbs) /* Math.abs ( x ) */ \
V("acos", Acos, 1, MathAcos) /* Math.acos ( x ) */ \
V("acosh", Acosh, 1, MathAcosh) /* Math.acosh ( x ) */ \
V("asin", Asin, 1, MathAsin) /* Math.asin ( x ) */ \
V("asinh", Asinh, 1, MathAsinh) /* Math.asinh ( x ) */ \
V("atan", Atan, 1, MathAtan) /* Math.atan ( x ) */ \
V("atan2", Atan2, 2, MathAtan2) /* Math.atan2 ( y, x ) */ \
V("atanh", Atanh, 1, MathAtanh) /* Math.atanh ( x ) */ \
V("cbrt", Cbrt, 1, INVALID) /* Math.cbrt ( x ) */ \
V("ceil", Ceil, 1, INVALID) /* Math.ceil ( x ) */ \
V("clz32", Clz32, 1, INVALID) /* Math.clz32 ( x ) */ \
V("cos", Cos, 1, COS) /* Math.cos ( x ) */ \
V("cosh", Cosh, 1, INVALID) /* Math.cosh ( x ) */ \
V("cos", Cos, 1, MathCos) /* Math.cos ( x ) */ \
V("cosh", Cosh, 1, MathCosh) /* Math.cosh ( x ) */ \
V("exp", Exp, 1, INVALID) /* Math.exp ( x ) */ \
V("expm1", Expm1, 1, INVALID) /* Math.expm1 ( x ) */ \
V("floor", Floor, 1, FLOOR) /* Math.floor ( x ) */ \
V("fround", Fround, 1, INVALID) /* Math.fround ( x ) */ \
V("hypot", Hypot, 2, INVALID) /* Math.hypot ( ...args ) */ \
V("imul", Imul, 2, INVALID) /* Math.imul ( x, y ) */ \
V("log", Log, 1, INVALID) /* Math.log ( x ) */ \
V("log10", Log10, 1, INVALID) /* Math.log10 ( x ) */ \
V("log1p", Log1p, 1, INVALID) /* Math.log1p ( x ) */ \
V("log2", Log2, 1, INVALID) /* Math.log2 ( x ) */ \
V("log", Log, 1, MathLog) /* Math.log ( x ) */ \
V("log10", Log10, 1, MathLog10) /* Math.log10 ( x ) */ \
V("log1p", Log1p, 1, MathLog1p) /* Math.log1p ( x ) */ \
V("log2", Log2, 1, MathLog2) /* Math.log2 ( x ) */ \
V("max", Max, 2, INVALID) /* Math.max ( ...args ) */ \
V("min", Min, 2, INVALID) /* Math.min ( ...args ) */ \
V("pow", Pow, 2, INVALID) /* Math.pow ( base, exponent ) */ \
V("pow", Pow, 2, MathPow) /* Math.pow ( base, exponent ) */ \
V("random", Random, 0, INVALID) /* Math.random ( ) */ \
V("round", Round, 1, INVALID) /* Math.round ( x ) */ \
V("sign", Sign, 1, INVALID) /* Math.sign ( x ) */ \
V("sin", Sin, 1, SIN) /* Math.sin ( x ) */ \
V("sinh", Sinh, 1, INVALID) /* Math.sinh ( x ) */ \
V("sin", Sin, 1, MathSin) /* Math.sin ( x ) */ \
V("sinh", Sinh, 1, MathSinh) /* Math.sinh ( x ) */ \
V("sqrt", Sqrt, 1, SQRT) /* Math.sqrt ( x ) */ \
V("tan", Tan, 1, INVALID) /* Math.tan ( x ) */ \
V("tanh", Tanh, 1, INVALID) /* Math.tanh ( x ) */ \
V("tan", Tan, 1, MathTan) /* Math.tan ( x ) */ \
V("tanh", Tanh, 1, MathTanh) /* Math.tanh ( x ) */ \
V("trunc", Trunc, 1, INVALID) /* Math.trunc ( x ) */
namespace panda::ecmascript::builtins {

View File

@ -187,6 +187,7 @@ libark_jsoptimizer_sources = [
"typed_array_stub_builder.cpp",
"typed_bytecode_lowering.cpp",
"typed_hcr_lowering.cpp",
"typed_native_inline_lowering.cpp",
"value_numbering.cpp",
"verifier.cpp",
]

View File

@ -118,11 +118,6 @@ namespace panda::ecmascript::kungfu {
#define AOT_BUILTINS_STUB_LIST(V) \
V(SQRT) /* list start and math list start */ \
V(COS) \
V(SIN) \
V(ACOS) \
V(ATAN) \
V(ABS) \
V(FLOOR) /* math list end */ \
V(STRINGIFY) \
V(MAP_PROTO_ITERATOR) \
@ -136,16 +131,39 @@ namespace panda::ecmascript::kungfu {
V(ARRAY_ITERATOR_PROTO_NEXT) \
V(ITERATOR_PROTO_RETURN)
// List of builtins which will try to be inlined in TypedNativeInlineLoweringPass
#define AOT_BUILTINS_INLINE_LIST(V) \
V(MathAcos) \
V(MathAcosh) \
V(MathAsin) \
V(MathAsinh) \
V(MathAtan) \
V(MathAtan2) \
V(MathAtanh) \
V(MathCos) \
V(MathCosh) \
V(MathSin) \
V(MathSinh) \
V(MathTan) \
V(MathTanh) \
V(MathLog) \
V(MathLog2) \
V(MathLog10) \
V(MathLog1p) \
V(MathPow) \
V(MathAbs) \
V(TYPED_BUILTINS_INLINE_FIRST = MathAcos) \
V(TYPED_BUILTINS_INLINE_LAST = MathAbs)
class BuiltinsStubCSigns {
public:
enum ID {
#define DEF_STUB_ID(name) name,
PADDING_BUILTINS_STUB_LIST(DEF_STUB_ID)
BUILTINS_STUB_LIST(DEF_STUB_ID)
#undef DEF_STUB_ID
NUM_OF_BUILTINS_STUBS,
#define DEF_STUB_ID(name) name,
AOT_BUILTINS_STUB_LIST(DEF_STUB_ID)
AOT_BUILTINS_INLINE_LIST(DEF_STUB_ID)
#undef DEF_STUB_ID
BUILTINS_CONSTRUCTOR_STUB_FIRST = BooleanConstructor,
TYPED_BUILTINS_FIRST = SQRT,
@ -197,7 +215,17 @@ public:
static bool IsTypedInlineBuiltin(ID builtinId)
{
return BuiltinsStubCSigns::ID::StringFromCharCode == builtinId;
if (TYPED_BUILTINS_INLINE_FIRST <= builtinId && builtinId <= TYPED_BUILTINS_INLINE_LAST) {
return true;
}
// NOTE(schernykh): try to remove this switch and move StringFromCharCode to TYPED_BUILTINS_INLINE list
switch (builtinId) {
case BuiltinsStubCSigns::ID::StringFromCharCode:
return true;
default:
return false;
}
return false;
}
static bool IsTypedBuiltinMath(ID builtinId)
@ -238,16 +266,44 @@ public:
static ConstantIndex GetConstantIndex(ID builtinId)
{
switch (builtinId) {
case BuiltinsStubCSigns::ID::COS:
return ConstantIndex::MATH_COS_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::SIN:
return ConstantIndex::MATH_SIN_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::ACOS:
return ConstantIndex::MATH_ACOS_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::ATAN:
return ConstantIndex::MATH_ATAN_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::ABS:
return ConstantIndex::MATH_ABS_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::MathAcos:
return ConstantIndex::MATH_ACOS_INDEX;
case BuiltinsStubCSigns::ID::MathAcosh:
return ConstantIndex::MATH_ACOSH_INDEX;
case BuiltinsStubCSigns::ID::MathAsin:
return ConstantIndex::MATH_ASIN_INDEX;
case BuiltinsStubCSigns::ID::MathAsinh:
return ConstantIndex::MATH_ASINH_INDEX;
case BuiltinsStubCSigns::ID::MathAtan:
return ConstantIndex::MATH_ATAN_INDEX;
case BuiltinsStubCSigns::ID::MathAtan2:
return ConstantIndex::MATH_ATAN2_INDEX;
case BuiltinsStubCSigns::ID::MathAtanh:
return ConstantIndex::MATH_ATANH_INDEX;
case BuiltinsStubCSigns::ID::MathCos:
return ConstantIndex::MATH_COS_INDEX;
case BuiltinsStubCSigns::ID::MathCosh:
return ConstantIndex::MATH_COSH_INDEX;
case BuiltinsStubCSigns::ID::MathSin:
return ConstantIndex::MATH_SIN_INDEX;
case BuiltinsStubCSigns::ID::MathSinh:
return ConstantIndex::MATH_SINH_INDEX;
case BuiltinsStubCSigns::ID::MathTan:
return ConstantIndex::MATH_TAN_INDEX;
case BuiltinsStubCSigns::ID::MathTanh:
return ConstantIndex::MATH_TANH_INDEX;
case BuiltinsStubCSigns::ID::MathAbs:
return ConstantIndex::MATH_ABS_INDEX;
case BuiltinsStubCSigns::ID::MathLog:
return ConstantIndex::MATH_LOG_INDEX;
case BuiltinsStubCSigns::ID::MathLog2:
return ConstantIndex::MATH_LOG2_INDEX;
case BuiltinsStubCSigns::ID::MathLog10:
return ConstantIndex::MATH_LOG10_INDEX;
case BuiltinsStubCSigns::ID::MathLog1p:
return ConstantIndex::MATH_LOG1P_INDEX;
case BuiltinsStubCSigns::ID::MathPow:
return ConstantIndex::MATH_POW_INDEX;
case BuiltinsStubCSigns::ID::FLOOR:
return ConstantIndex::MATH_FLOOR_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::SQRT:
@ -281,12 +337,26 @@ public:
static ID GetBuiltinId(std::string idStr)
{
const std::map<std::string, BuiltinsStubCSigns::ID> str2BuiltinId = {
{"Acos", MathAcos},
{"Acosh", MathAcosh},
{"Asin", MathAsin},
{"Asinh", MathAsinh},
{"Atan", MathAtan},
{"Atan2", MathAtan2},
{"Atanh", MathAtanh},
{"Cos", MathCos},
{"Cosh", MathCosh},
{"Sin", MathSin},
{"Sinh", MathSinh},
{"Tan", MathTan},
{"Tanh", MathTanh},
{"Log", MathLog},
{"Log2", MathLog2},
{"Log10", MathLog10},
{"Log1p", MathLog1p},
{"sqrt", SQRT},
{"cos", COS},
{"sin", SIN},
{"acos", ACOS},
{"atan", ATAN},
{"abs", ABS},
{"abs", MathAbs},
{"pow", MathPow},
{"floor", FLOOR},
{"localeCompare", LocaleCompare},
{"sort", SORT},

View File

@ -25,15 +25,8 @@ void BuiltinLowering::LowerTypedCallBuitin(GateRef gate)
auto idGate = acc_.GetValueIn(gate, valuesIn - 1);
auto id = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(idGate));
switch (id) {
case BUILTINS_STUB_ID(ABS):
LowerTypedAbs(gate);
break;
case BUILTINS_STUB_ID(FLOOR):
case BUILTINS_STUB_ID(COS):
case BUILTINS_STUB_ID(SIN):
case BUILTINS_STUB_ID(ACOS):
case BUILTINS_STUB_ID(ATAN):
LowerTypedTrigonometric(gate, id);
LowerTypedFloor(gate);
break;
case BUILTINS_STUB_ID(LocaleCompare):
LowerTypedLocaleCompare(gate);
@ -68,13 +61,13 @@ void BuiltinLowering::LowerTypedCallBuitin(GateRef gate)
}
}
void BuiltinLowering::LowerTypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID id)
void BuiltinLowering::LowerTypedFloor(GateRef gate)
{
auto ret = TypedTrigonometric(gate, id);
auto ret = TypedFloor(gate);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
}
GateRef BuiltinLowering::TypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID id)
GateRef BuiltinLowering::TypedFloor(GateRef gate)
{
auto env = builder_.GetCurrentEnvironment();
Label entry(&builder_);
@ -98,28 +91,9 @@ GateRef BuiltinLowering::TypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID
builder_.Bind(&NotNan);
{
GateRef glue = acc_.GetGlueFromArgList();
int index = RTSTUB_ID(FloatCos);
switch (id) {
case BUILTINS_STUB_ID(FLOOR):
index = RTSTUB_ID(FloatFloor);
break;
case BUILTINS_STUB_ID(ACOS):
index = RTSTUB_ID(FloatACos);
break;
case BUILTINS_STUB_ID(ATAN):
index = RTSTUB_ID(FloatATan);
break;
case BUILTINS_STUB_ID(COS):
index = RTSTUB_ID(FloatCos);
break;
case BUILTINS_STUB_ID(SIN):
index = RTSTUB_ID(FloatSin);
break;
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
result = builder_.CallNGCRuntime(glue, index, Gate::InvalidGateRef, {value}, gate);
int index = RTSTUB_ID(FloatFloor);
GateRef floor = builder_.CallNGCRuntime(glue, index, Gate::InvalidGateRef, {value}, gate);
result = builder_.DoubleToTaggedDoublePtr(floor);
builder_.Jump(&exit);
}
builder_.Bind(&IsNan);
@ -152,60 +126,12 @@ void BuiltinLowering::LowerTypedSqrt(GateRef gate)
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
}
void BuiltinLowering::LowerTypedAbs(GateRef gate)
{
auto ret = TypedAbs(gate);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
}
GateRef BuiltinLowering::IntToTaggedIntPtr(GateRef x)
{
GateRef val = builder_.SExtInt32ToInt64(x);
return builder_.ToTaggedIntPtr(val);
}
// Int abs : The internal representation of an integer is inverse code,
// The absolute value of a negative number can be found by inverting it by adding one.
// Float abs : A floating-point number is composed of mantissa and exponent.
// The length of mantissa will affect the precision of the number, and its sign will determine the sign of the number.
// The absolute value of a floating-point number can be found by setting mantissa sign bit to 0.
GateRef BuiltinLowering::TypedAbs(GateRef gate)
{
auto env = builder_.GetCurrentEnvironment();
Label entry(&builder_);
env->SubCfgEntry(&entry);
Label exit(&builder_);
GateRef para1 = acc_.GetValueIn(gate, 0);
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
Label isInt(&builder_);
Label notInt(&builder_);
builder_.Branch(builder_.TaggedIsInt(para1), &isInt, &notInt);
builder_.Bind(&isInt);
{
auto value = builder_.GetInt32OfTInt(para1);
auto temp = builder_.Int32ASR(value, builder_.Int32(JSTaggedValue::INT_SIGN_BIT_OFFSET));
auto res = builder_.Int32Xor(value, temp);
result = IntToTaggedIntPtr(builder_.Int32Sub(res, temp));
builder_.Jump(&exit);
}
builder_.Bind(&notInt);
{
auto value = builder_.GetDoubleOfTDouble(para1);
// set the sign bit to 0 by shift left then right.
auto temp = builder_.Int64LSL(builder_.CastDoubleToInt64(value), builder_.Int64(1));
auto res = builder_.Int64LSR(temp, builder_.Int64(1));
result = builder_.DoubleToTaggedDoublePtr(builder_.CastInt64ToFloat64(res));
builder_.Jump(&exit);
}
builder_.Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
GateRef BuiltinLowering::LowerCallRuntime(GateRef glue, GateRef gate, int index, const std::vector<GateRef> &args,
bool useLabel)
{
@ -358,13 +284,15 @@ GateRef BuiltinLowering::CheckPara(GateRef gate, GateRef funcCheck)
{
GateRef idGate = acc_.GetValueIn(gate, 1);
BuiltinsStubCSigns::ID id = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(idGate));
if (IS_TYPED_INLINE_BUILTINS_ID(id)) {
// Don't need check param. Param was checked before
return funcCheck;
}
switch (id) {
case BuiltinsStubCSigns::ID::COS:
case BuiltinsStubCSigns::ID::SIN:
case BuiltinsStubCSigns::ID::ACOS:
case BuiltinsStubCSigns::ID::ATAN:
case BuiltinsStubCSigns::ID::ABS:
case BuiltinsStubCSigns::ID::FLOOR: {
if (acc_.GetNumValueIn(gate) <= 2U) {
return funcCheck;
}
GateRef para = acc_.GetValueIn(gate, 2);
GateRef paracheck = builder_.TaggedIsNumber(para);
return builder_.BoolAnd(paracheck, funcCheck);
@ -386,7 +314,6 @@ GateRef BuiltinLowering::CheckPara(GateRef gate, GateRef funcCheck)
case BuiltinsStubCSigns::ID::ARRAY_ITERATOR_PROTO_NEXT:
case BuiltinsStubCSigns::ID::ITERATOR_PROTO_RETURN:
case BuiltinsStubCSigns::ID::NumberConstructor:
case BuiltinsStubCSigns::ID::StringFromCharCode:
// Don't need check para
return funcCheck;
default: {

View File

@ -34,11 +34,9 @@ public:
void LowerTypedArraySort(GateRef gate);
private:
void LowerTypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID id);
GateRef TypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID id);
void LowerTypedFloor(GateRef gate);
GateRef TypedFloor(GateRef gate);
GateRef IntToTaggedIntPtr(GateRef x);
void LowerTypedAbs(GateRef gate);
GateRef TypedAbs(GateRef gate);
GateRef LowerCallRuntime(GateRef glue, GateRef gate, int index, const std::vector<GateRef> &args,
bool useLabel = false);
void ReplaceHirWithValue(GateRef hirGate, GateRef value, bool noThrow = false);

View File

@ -1866,21 +1866,6 @@ DEF_CALL_SIGNATURE(InsertLocalToShareRSet)
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
DEF_CALL_SIGNATURE(FloatMod)
{
// 2 : 2 input parameters
CallSignature index("FloatMod", 0, 2, ArgumentsOrder::DEFAULT_ORDER, VariableType::FLOAT64());
*callSign = index;
// 2 : 2 input parameters
std::array<VariableType, 2> params = {
VariableType::FLOAT64(),
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
DEF_CALL_SIGNATURE(FloatSqrt)
{
// 1 : 1 input parameters
@ -1895,75 +1880,62 @@ DEF_CALL_SIGNATURE(FloatSqrt)
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
DEF_CALL_SIGNATURE(FloatCos)
{
// 1 : 1 input parameters
CallSignature index("FloatCos", 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = index;
// 1 : 1 input parameters
std::array<VariableType, 1> params = {
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
#define DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(NAME) \
DEF_CALL_SIGNATURE(NAME) \
{ \
/* 1 : 1 input parameters */ \
CallSignature index(#NAME, 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::FLOAT64()); \
*callSign = index; \
/* 1 : 1 input parameters */ \
std::array<VariableType, 1> params = { \
VariableType::FLOAT64(), \
}; \
callSign->SetParameters(params.data()); \
callSign->SetGCLeafFunction(true); \
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC); \
}
DEF_CALL_SIGNATURE(FloatSin)
{
// 1 : 1 input parameters
CallSignature index("FloatSin", 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = index;
// 1 : 1 input parameters
std::array<VariableType, 1> params = {
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatAcos)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatAcosh)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatAsin)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatAsinh)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatAtan)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatAtanh)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatCos)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatCosh)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatSin)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatSinh)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatTan)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatTanh)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatFloor)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatLog)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatLog2)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatLog10)
DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME(FloatLog1p)
DEF_CALL_SIGNATURE(FloatACos)
{
// 1 : 1 input parameters
CallSignature index("FloatACos", 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = index;
// 1 : 1 input parameters
std::array<VariableType, 1> params = {
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
#undef DEF_FLOAT_UNARY_CALL_SIGNATURE_BY_NAME
DEF_CALL_SIGNATURE(FloatATan)
{
// 1 : 1 input parameters
CallSignature index("FloatATan", 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = index;
// 1 : 1 input parameters
std::array<VariableType, 1> params = {
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
#define DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME(NAME) \
DEF_CALL_SIGNATURE(NAME) \
{ \
/* 2 : 2 input parameters */ \
CallSignature index(#NAME, 0, 2, ArgumentsOrder::DEFAULT_ORDER, VariableType::FLOAT64()); \
*callSign = index; \
/* 2 : 2 input parameters */ \
std::array<VariableType, 2> params = { \
VariableType::FLOAT64(), \
VariableType::FLOAT64(), \
}; \
callSign->SetParameters(params.data()); \
callSign->SetGCLeafFunction(true); \
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC); \
}
DEF_CALL_SIGNATURE(FloatFloor)
{
// 1 : 1 input parameters
CallSignature index("FloatFloor", 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = index;
// 1 : 1 input parameters
std::array<VariableType, 1> params = {
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME(FloatMod)
DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME(FloatAtan2)
DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME(FloatPow)
#undef DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME
DEF_CALL_SIGNATURE(FindElementWithCache)
{

View File

@ -442,11 +442,25 @@ private:
V(DoubleToLength) \
V(FloatMod) \
V(FloatSqrt) \
V(FloatAcos) \
V(FloatAcosh) \
V(FloatAsin) \
V(FloatAsinh) \
V(FloatAtan) \
V(FloatAtan2) \
V(FloatAtanh) \
V(FloatCos) \
V(FloatCosh) \
V(FloatSin) \
V(FloatACos) \
V(FloatATan) \
V(FloatSinh) \
V(FloatTan) \
V(FloatTanh) \
V(FloatLog) \
V(FloatLog2) \
V(FloatLog10) \
V(FloatLog1p) \
V(FloatFloor) \
V(FloatPow) \
V(FindElementWithCache) \
V(MarkingBarrier) \
V(StoreBarrier) \

View File

@ -218,8 +218,10 @@ public:
private:
static const size_t CIRCUIT_SPACE = 1U << 30U; // 1GB
public:
void Print(GateRef gate) const;
private:
GateType GetGateType(GateRef gate) const;
GateRef GetGateRef(const Gate *gate) const;
MachineType GetMachineType(GateRef gate) const;

View File

@ -478,7 +478,9 @@ public:
GateRef ObjectTypeCheck(GateType type, bool isHeapObject, GateRef gate, GateRef hclassIndex,
GateRef frameState = Gate::InvalidGateRef);
GateRef TryPrimitiveTypeCheck(GateType type, GateRef gate);
GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, GateRef param, const char* comment = nullptr);
GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, const char* comment = nullptr);
GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, std::vector<GateRef> params,
const char* comment = nullptr);
GateRef JSCallTargetFromDefineFuncCheck(GateType type, GateRef func, GateRef gate);
template<TypedCallTargetCheckOp Op>
GateRef JSCallTargetTypeCheck(GateType type, GateRef func, GateRef methodIndex, GateRef gate);
@ -772,6 +774,7 @@ public:
static MachineType GetMachineTypeFromVariableType(VariableType type);
// Unary / BinaryOp
GateRef BuildMathBuiltinOp(const GateMetaData* op, std::vector<GateRef> args);
template<OpCode Op, MachineType Type>
inline GateRef BinaryOp(GateRef x, GateRef y);
template<OpCode Op, MachineType Type>
@ -805,6 +808,8 @@ public:
#undef CMP_BINARY_OP_WITHOUT_BITWIDTH
private:
std::vector<GateRef> ConcatParams(const std::vector<std::vector<GateRef>>& params);
static constexpr uint32_t GATE_TWO_VALUESIN = 2;
inline void SetDepend(GateRef depend);

View File

@ -73,12 +73,15 @@ Environment::~Environment()
Label::Label(Environment *env)
{
ASSERT(env != nullptr);
impl_ = env->NewLabel(env);
}
Label::Label(CircuitBuilder *cirBuilder)
{
ASSERT(cirBuilder != nullptr);
auto env = cirBuilder->GetCurrentEnvironment();
ASSERT(env != nullptr);
impl_ = env->NewLabel(env);
}

View File

@ -541,7 +541,22 @@ GateRef CircuitBuilder::TryPrimitiveTypeCheck(GateType type, GateRef gate)
return ret;
}
GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef id, GateRef param, const char* comment)
std::vector<GateRef> CircuitBuilder::ConcatParams(const std::vector<std::vector<GateRef>>& params)
{
std::vector<GateRef> unionParams;
for (auto param: params) {
unionParams.insert(unionParams.end(), param.begin(), param.end());
}
return unionParams;
}
GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef id, const char* comment)
{
return CallTargetCheck(gate, function, id, {}, comment);
}
GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef id, std::vector<GateRef> params,
const char* comment)
{
auto currentLabel = env_->GetCurrentLabel();
auto currentControl = currentLabel->GetControl();
@ -552,9 +567,10 @@ GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef
} else {
frameState = acc_.FindNearestFrameState(currentDepend);
}
GateRef ret = GetCircuit()->NewGate(circuit_->TypedCallCheck(),
auto params_vec = ConcatParams({{ currentControl, currentDepend, function, id }, params, {frameState}});
GateRef ret = GetCircuit()->NewGate(circuit_->TypedCallCheck(params.size() + 2),
MachineType::I1,
{ currentControl, currentDepend, function, id, param, frameState},
params_vec,
GateType::NJSValue(),
comment);
currentLabel->SetControl(ret);
@ -1550,6 +1566,19 @@ GateRef CircuitBuilder::ToNumber(GateRef gate, GateRef value, GateRef glue)
return ret;
}
GateRef CircuitBuilder::BuildMathBuiltinOp(const GateMetaData* op, std::vector<GateRef> args)
{
auto currentLabel = env_->GetCurrentLabel();
auto currentControl = currentLabel->GetControl();
auto currentDepend = currentLabel->GetDepend();
GateRef ret =
GetCircuit()->NewGate(op, MachineType::I64,
ConcatParams({std::vector{ currentControl, currentDepend}, args}), GateType::AnyType());
currentLabel->SetControl(ret);
currentLabel->SetDepend(ret);
return ret;
}
GateRef CircuitBuilder::StringFromSingleCharCode(GateRef gate)
{
auto currentLabel = env_->GetCurrentLabel();

View File

@ -50,7 +50,6 @@ namespace panda::ecmascript::kungfu {
V(LoadStringLength, LOAD_STRING_LENGTH, GateFlags::NO_WRITE, 1, 1, 1) \
V(StartAllocate, START_ALLOCATE, GateFlags::NONE_FLAG, 0, 1, 0) \
V(StorePropertyNoBarrier, STORE_PROPERTY_NO_BARRIER, GateFlags::NONE_FLAG, 1, 1, 3) \
V(TypedCallCheck, TYPED_CALL_CHECK, GateFlags::CHECKABLE, 1, 1, 3) \
V(TypedNewAllocateThis, TYPED_NEW_ALLOCATE_THIS, GateFlags::CHECKABLE, 1, 1, 2) \
V(TypedSuperAllocateThis, TYPED_SUPER_ALLOCATE_THIS, GateFlags::CHECKABLE, 1, 1, 2) \
V(ArrayConstructorCheck, ARRAY_CONSTRUCTOR_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
@ -62,6 +61,25 @@ namespace panda::ecmascript::kungfu {
V(MigrateFromHeapValueToRawValue, MIGRATE_FROM_HEAPVALUE_TO_RAWVALUE, GateFlags::NONE_FLAG, 1, 1, 3) \
V(MigrateFromHoleIntToHoleNumber, MIGRATE_FROM_HOLEINT_TO_HOLENUMBER, GateFlags::NONE_FLAG, 1, 1, 1) \
V(MigrateFromHoleNumberToHoleInt, MIGRATE_FROM_HOLENUMBER_TO_HOLEINT, GateFlags::NONE_FLAG, 1, 1, 1) \
V(MathAcos, MATH_ACOS, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathAcosh, MATH_ACOSH, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathAsin, MATH_ASIN, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathAsinh, MATH_ASINH, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathAtan, MATH_ATAN, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathAtan2, MATH_ATAN2, GateFlags::NO_WRITE, 1, 1, 2) \
V(MathAtanh, MATH_ATANH, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathCos, MATH_COS, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathCosh, MATH_COSH, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathSin, MATH_SIN, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathSinh, MATH_SINH, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathTan, MATH_TAN, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathTanh, MATH_TANH, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathLog, MATH_LOG, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathLog2, MATH_LOG2, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathLog10, MATH_LOG10, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathLog1p, MATH_LOG1P, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathAbs, MATH_ABS, GateFlags::NO_WRITE, 1, 1, 1) \
V(MathPow, MATH_POW, GateFlags::NO_WRITE, 1, 1, 2) \
MCR_BINARY_GATE_META_DATA_CACHE_LIST(V)
#define MCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(V) \
@ -124,7 +142,8 @@ namespace panda::ecmascript::kungfu {
}
#define MCR_GATE_META_DATA_LIST_WITH_VALUE_IN(V) \
V(TypedCreateObjWithBuffer, TYPED_CREATE_OBJ_WITH_BUFFER, GateFlags::CHECKABLE, 1, 1, value)
V(TypedCreateObjWithBuffer, TYPED_CREATE_OBJ_WITH_BUFFER, GateFlags::CHECKABLE, 1, 1, value) \
V(TypedCallCheck, TYPED_CALL_CHECK, GateFlags::CHECKABLE, 1, 1, value)
#define MCR_GATE_META_DATA_LIST_WITH_SIZE(V) \
MCR_GATE_META_DATA_LIST_WITH_VALUE_IN(V)

View File

@ -20,21 +20,107 @@
#include "ecmascript/message_string.h"
namespace panda::ecmascript::kungfu {
std::optional<size_t> NativeInlineLowering::GetArgc(GateRef gate)
{
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
case EcmaOpcode::CALLTHIS0_IMM8_V8:
return 0U;
case EcmaOpcode::CALLTHIS1_IMM8_V8_V8:
return 1U;
case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8:
return 2U;
case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8:
return 3U;
case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8: {
CallThisRangeTypeInfoAccessor tia(thread_, circuit_, gate);
return tia.GetArgc();
}
default:
return std::nullopt;
}
}
void NativeInlineLowering::RunNativeInlineLowering()
{
std::vector<GateRef> gateList;
circuit_->GetAllGates(gateList);
for (const auto &gate : gateList) {
auto op = acc_.GetOpCode(gate);
if (op == OpCode::JS_BYTECODE) {
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
case EcmaOpcode::CALLTHIS1_IMM8_V8_V8:
TryInlineNativeCallThis1(gate);
break;
default:
break;
}
if (op != OpCode::JS_BYTECODE) {
continue;
}
std::optional<size_t> opt_argc = GetArgc(gate);
if (!opt_argc) {
continue;
}
size_t argc = opt_argc.value();
CallTypeInfoAccessor ctia(thread_, circuit_, gate);
BuiltinsStubCSigns::ID id = ctia.TryGetPGOBuiltinId();
switch (id) {
case BuiltinsStubCSigns::ID::StringFromCharCode:
TryInlineStringFromCharCode(gate, argc);
break;
case BuiltinsStubCSigns::ID::MathAcos:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAcos());
break;
case BuiltinsStubCSigns::ID::MathAcosh:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAcosh());
break;
case BuiltinsStubCSigns::ID::MathAsin:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAsin());
break;
case BuiltinsStubCSigns::ID::MathAsinh:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAsinh());
break;
case BuiltinsStubCSigns::ID::MathAtan:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAtan());
break;
case BuiltinsStubCSigns::ID::MathAtan2:
TryInlineMathBinaryBuiltin(gate, argc, id, circuit_->MathAtan2());
break;
case BuiltinsStubCSigns::ID::MathAtanh:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAtanh());
break;
case BuiltinsStubCSigns::ID::MathCos:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathCos());
break;
case BuiltinsStubCSigns::ID::MathCosh:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathCosh());
break;
case BuiltinsStubCSigns::ID::MathSin:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathSin());
break;
case BuiltinsStubCSigns::ID::MathSinh:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathSinh());
break;
case BuiltinsStubCSigns::ID::MathTan:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathTan());
break;
case BuiltinsStubCSigns::ID::MathTanh:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathTanh());
break;
case BuiltinsStubCSigns::ID::MathAbs:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAbs());
break;
case BuiltinsStubCSigns::ID::MathLog:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog());
break;
case BuiltinsStubCSigns::ID::MathLog2:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog2());
break;
case BuiltinsStubCSigns::ID::MathLog10:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog10());
break;
case BuiltinsStubCSigns::ID::MathLog1p:
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog1p());
break;
case BuiltinsStubCSigns::ID::MathPow:
TryInlineMathBinaryBuiltin(gate, argc, id, circuit_->MathPow());
break;
default:
break;
}
}
@ -49,199 +135,56 @@ void NativeInlineLowering::RunNativeInlineLowering()
}
}
void NativeInlineLowering::TryInlineNativeCallThis1(GateRef gate)
void NativeInlineLowering::TryInlineStringFromCharCode(GateRef gate, size_t argc)
{
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
BuiltinsStubCSigns::ID id = tacc.TryGetPGOBuiltinId();
switch (id) {
case BuiltinsStubCSigns::ID::StringFromCharCode: {
TryInlineStringFromCharCode(gate, tacc);
break;
}
default:
break;
}
}
void NativeInlineLowering::TryInlineStringFromCharCode(GateRef gate, CallThis1TypeInfoAccessor &tacc)
{
if (acc_.GetByteCodeOpcode(gate) != EcmaOpcode::CALLTHIS1_IMM8_V8_V8) {
if (argc != 1) {
return;
}
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
Environment env(gate, circuit_, &builder_);
if (!Uncheck()) {
builder_.CallTargetCheck(gate, tacc.GetFunc(),
builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringFromCharCode)),
tacc.GetArg0());
{tacc.GetArg0()});
}
GateRef ret = builder_.StringFromSingleCharCode(tacc.GetArg0());
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
}
void NativeInlineLowering::TryInlineBuiltinsArrayFunc(GateRef gate)
{
GateRef func = acc_.GetValueIn(gate, acc_.GetNumValueIn(gate) - 1); // 1: last value in
GateType funcType = acc_.GetGateType(func);
if (tsManager_->IsBuiltinObjectMethod(BuiltinTypeId::ARRAY, funcType)) {
std::string name = tsManager_->GetFuncName(funcType);
if (name == "forEach") {
RunArrayForeachInline(gate);
}
}
}
void NativeInlineLowering::RunArrayForeachInline(GateRef gate)
void NativeInlineLowering::TryInlineMathUnaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
const GateMetaData* op)
{
Environment env(gate, circuit_, &builder_);
GateRef thisObj = acc_.GetValueIn(gate, 0);
GateRef callBack = acc_.GetValueIn(gate, 1);
GateRef thisArg = builder_.Undefined();
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
if (ecmaOpcode == EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8) {
thisArg = acc_.GetValueIn(gate, 2); // 2: this arg parameter
if (!Uncheck()) {
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1),
builder_.IntPtr(static_cast<int64_t>(id)));
}
builder_.BuiltinPrototypeHClassCheck(thisObj, BuiltinTypeId::ARRAY);
ElementsKind kind = acc_.TryGetArrayElementsKind(thisObj);
if (!IsCreateArray(thisObj)) {
builder_.StableArrayCheck(thisObj, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
// NOTE(schernykh): Add tracing
if (argc == 0) {
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.NanValue());
return;
}
Label callBackIsCallable(&builder_);
Label callBackNotCallable(&builder_);
builder_.Branch(builder_.IsCallable(callBack), &callBackIsCallable, &callBackNotCallable);
builder_.Bind(&callBackNotCallable);
{
GateRef taggedId = builder_.Int64(GET_MESSAGE_STRING_ID(NonCallable));
LowerCallRuntime(glue_, gate, RTSTUB_ID(ThrowTypeError), { builder_.ToTaggedIntPtr(taggedId) }, true);
GateRef exception = builder_.ExceptionConstant();
builder_.Return(exception);
}
builder_.Bind(&callBackIsCallable);
Label exit(&builder_);
ArrayForeachCall(gate, thisObj, callBack, thisArg, &exit);
builder_.Bind(&exit);
ReplaceHirDirectly(gate, builder_.Undefined());
GateRef ret = builder_.BuildMathBuiltinOp(op, {acc_.GetValueIn(gate, 1)});
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
}
void NativeInlineLowering::ArrayForeachCall(GateRef gate, GateRef thisObj, GateRef callBack, GateRef thisArg,
Label *exit)
void NativeInlineLowering::TryInlineMathBinaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
const GateMetaData* op)
{
GateRef length = builder_.LoadArrayLength(thisObj);
Label loopHead(&builder_);
Label loopEnd(&builder_);
Label exitloop(&builder_);
Label slowForeach(&builder_);
DEFVALUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0));
DEFVALUE(propKey, (&builder_), VariableType::JS_ANY(), builder_.ToTaggedIntPtr(builder_.SExtInt32ToInt64(*i)));
DEFVALUE(value, (&builder_), VariableType::JS_ANY(), builder_.Hole());
builder_.Branch(builder_.Int32LessThan(*i, length), &loopHead, &exitloop);
builder_.LoopBegin(&loopHead);
ElementsKind kind = acc_.TryGetArrayElementsKind(thisObj);
value = LoadArrayElement(kind, thisObj, *i);
Label NotHole(&builder_);
Label merge(&builder_);
builder_.Branch(builder_.NotEqual(*value, builder_.Hole()), &NotHole, &exitloop);
builder_.Bind(&NotHole);
{
auto depend = builder_.GetDepend();
GateRef nativeCall = NativeCallTS(gate, depend,
{glue_, builder_.Int64(6), callBack, builder_.Undefined(), thisArg, *value, *propKey, thisObj}); // 6: args
builder_.SetDepend(nativeCall);
i = builder_.Int32Add(*i, builder_.Int32(1));
propKey = builder_.ToTaggedIntPtr(builder_.SExtInt32ToInt64(*i));
builder_.Branch(builder_.IsStabelArray(glue_, thisObj), &merge, &exitloop);
Environment env(gate, circuit_, &builder_);
if (!Uncheck()) {
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1),
builder_.IntPtr(static_cast<int64_t>(id)));
}
builder_.Bind(&merge);
builder_.Branch(builder_.Int32LessThan(*i, length), &loopEnd, &exitloop);
builder_.Bind(&loopEnd);
builder_.LoopEnd(&loopHead);
builder_.Bind(&exitloop);
builder_.Branch(builder_.Int32LessThan(*i, length), &slowForeach, exit);
builder_.Bind(&slowForeach);
{
GateRef taggedLength = builder_.ToTaggedIntPtr(builder_.SExtInt32ToInt64(length));
GateRef slowPathCall = LowerCallRuntime(glue_, gate, RTSTUB_ID(ArrayForEachContinue),
{thisArg, *propKey, thisObj, callBack, taggedLength}, true);
builder_.SetDepend(slowPathCall);
builder_.Jump(exit);
// NOTE(schernykh): Add tracing
if (argc < 2U) {
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.NanValue());
return;
}
GateRef ret = builder_.BuildMathBuiltinOp(op, {acc_.GetValueIn(gate, 1), acc_.GetValueIn(gate, 2)});
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
return;
}
bool NativeInlineLowering::IsCreateArray(GateRef gate)
{
if (acc_.GetOpCode(gate) != OpCode::JS_BYTECODE) {
return false;
}
EcmaOpcode ecmaop = acc_.GetByteCodeOpcode(gate);
switch (ecmaop) {
case EcmaOpcode::CREATEEMPTYARRAY_IMM8:
case EcmaOpcode::CREATEEMPTYARRAY_IMM16:
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
return true;
default:
return false;
}
UNREACHABLE();
return false;
}
GateRef NativeInlineLowering::LoadArrayElement(ElementsKind kind, GateRef gate, GateRef index)
{
switch (kind) {
case ElementsKind::INT:
return builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_INT_ELEMENT>(gate, index);
case ElementsKind::NUMBER:
return builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_DOUBLE_ELEMENT>(gate, index);
case ElementsKind::OBJECT:
return builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_OBJECT_ELEMENT>(gate, index);
default:
if (!Elements::IsHole(kind)) {
return builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_TAGGED_ELEMENT>(gate, index);
}
}
return builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_HOLE_TAGGED_ELEMENT>(gate, index);
}
void NativeInlineLowering::ReplaceHirDirectly(GateRef gate, GateRef value)
{
GateRef state = builder_.GetState();
GateRef depend = builder_.GetDepend();
auto uses = acc_.Uses(gate);
for (auto it = uses.begin(); it != uses.end();) {
if (acc_.IsStateIn(it)) {
ASSERT(acc_.GetOpCode(*it) != OpCode::IF_SUCCESS &&
acc_.GetOpCode(*it) != OpCode::IF_EXCEPTION);
it = acc_.ReplaceIn(it, state);
} else if (acc_.IsDependIn(it)) {
it = acc_.ReplaceIn(it, depend);
} else {
ASSERT(acc_.IsValueIn(it));
it = acc_.ReplaceIn(it, value);
}
}
acc_.DeleteGate(gate);
}
GateRef NativeInlineLowering::LowerCallRuntime(GateRef glue, GateRef hirGate, int index,
const std::vector<GateRef> &args, bool useLabel)
{
if (useLabel) {
GateRef result = builder_.CallRuntime(glue, index, Gate::InvalidGateRef, args, hirGate);
return result;
} else {
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime));
GateRef target = builder_.IntPtr(index);
GateRef result = builder_.Call(cs, glue, target, acc_.GetDependRoot(), args, hirGate);
return result;
}
}
GateRef NativeInlineLowering::NativeCallTS(GateRef gate, GateRef depend, const std::vector<GateRef> &args)
{
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(JSCall));
GateRef target = builder_.IntPtr(RTSTUB_ID(JSCall));
GateRef call = builder_.Call(cs, glue_, target, depend, args, gate);
return call;
}
} // namespace panda::ecmascript

View File

@ -34,21 +34,18 @@ public:
enableLog_(enableLog),
methodName_(name),
nocheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()),
traceInline_(ctx->GetEcmaVM()->GetJSOptions().GetTraceInline()),
thread_(ctx->GetEcmaVM()->GetJSThread()) {}
~NativeInlineLowering() = default;
void RunNativeInlineLowering();
private:
void RunArrayForeachInline(GateRef gate);
void ArrayForeachCall(GateRef gate, GateRef thisObj, GateRef callBack, GateRef thisArg, Label *exit);
void TryInlineNativeCallThis1(GateRef gate);
void TryInlineBuiltinsArrayFunc(GateRef gate);
bool IsCreateArray(GateRef gate);
GateRef LoadArrayElement(ElementsKind kind, GateRef gate, GateRef index);
void ReplaceHirDirectly(GateRef gate, GateRef value);
GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args, bool useLabel);
GateRef NativeCallTS(GateRef gate, GateRef depend, const std::vector<GateRef> &args);
void TryInlineStringFromCharCode(GateRef gate, CallThis1TypeInfoAccessor &tacc);
std::optional<size_t> GetArgc(GateRef gate);
void TryInlineStringFromCharCode(GateRef gate, size_t argc);
void TryInlineMathMinWithOneArg(GateRef gate, size_t argc);
void TryInlineMathUnaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, const GateMetaData* op);
void TryInlineMathBinaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, const GateMetaData* op);
bool EnableLog() const
{
return enableLog_;
@ -64,6 +61,12 @@ private:
return nocheck_;
}
bool EnableTrace() const
{
return traceInline_;
}
private:
Circuit *circuit_ {nullptr};
CircuitBuilder builder_;
GateAccessor acc_;
@ -72,6 +75,7 @@ private:
bool enableLog_;
std::string methodName_;
bool nocheck_;
bool traceInline_;
const JSThread *thread_ {nullptr};
};
}

View File

@ -133,6 +133,27 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
return VisitIntermediateValue(gate);
case OpCode::NUMBER_TO_STRING:
return VisitNumberToString(gate);
case OpCode::MATH_LOG:
case OpCode::MATH_LOG2:
case OpCode::MATH_LOG10:
case OpCode::MATH_LOG1P:
case OpCode::MATH_ACOS:
case OpCode::MATH_ACOSH:
case OpCode::MATH_ASIN:
case OpCode::MATH_ASINH:
case OpCode::MATH_ATAN:
case OpCode::MATH_ATAN2:
case OpCode::MATH_ATANH:
case OpCode::MATH_COS:
case OpCode::MATH_COSH:
case OpCode::MATH_SIN:
case OpCode::MATH_SINH:
case OpCode::MATH_TAN:
case OpCode::MATH_TANH:
case OpCode::MATH_POW:
return VisitMathBuiltin(gate);
case OpCode::MATH_ABS:
return VisitMathAbs(gate);
case OpCode::JS_BYTECODE:
case OpCode::PRIMITIVE_TYPE_CHECK:
case OpCode::STABLE_ARRAY_CHECK:
@ -160,6 +181,7 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
case OpCode::ORDINARY_HAS_INSTANCE:
case OpCode::ECMA_STRING_CHECK:
case OpCode::CREATE_ARGUMENTS:
case OpCode::TAGGED_TO_INT64:
return VisitOthers(gate);
default:
return Circuit::NullGate();
@ -414,7 +436,8 @@ GateRef NumberSpeculativeRetype::VisitNumberBinaryOp(GateRef gate)
case TypedBinOp::TYPED_ADD:
case TypedBinOp::TYPED_SUB:
case TypedBinOp::TYPED_MUL:
case TypedBinOp::TYPED_DIV: {
case TypedBinOp::TYPED_DIV:
case TypedBinOp::TYPED_MOD: {
return VisitNumberCalculate(gate);
}
case TypedBinOp::TYPED_LESS:
@ -435,9 +458,6 @@ GateRef NumberSpeculativeRetype::VisitNumberBinaryOp(GateRef gate)
case TypedBinOp::TYPED_XOR: {
return VisitNumberShiftAndLogical(gate);
}
case TypedBinOp::TYPED_MOD: {
return VisitNumberMod(gate);
}
default:
return VisitNumberRelated(gate);
}
@ -646,7 +666,7 @@ GateRef NumberSpeculativeRetype::VisitNumberRelated(GateRef gate)
GateRef input = acc_.GetValueIn(gate, i);
GateType inputType = acc_.GetGateType(input);
if (inputType.IsNumberType() || inputType.IsBooleanType()) {
acc_.ReplaceValueIn(gate, CheckAndConvertToTagged(input, inputType), i);
acc_.ReplaceValueIn(gate, CheckAndConvertToTagged(input, inputType, ConvertToNumber::BOOL_ONLY), i);
}
}
acc_.ReplaceStateIn(gate, builder_.GetState());
@ -946,7 +966,8 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToInt32(GateRef gate, GateType g
return result;
}
GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType gateType, ConvertSupport support)
GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType gateType,
ConvertToNumber convert)
{
auto result = TryConvertConstant(gate, false);
if (result != Circuit::NullGate()) {
@ -957,7 +978,7 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType
TypeInfo output = GetOutputTypeInfo(gate);
switch (output) {
case TypeInfo::INT1:
result = builder_.ConvertBoolToFloat64(gate, support);
result = builder_.ConvertBoolToFloat64(gate, ToConvertSupport(convert));
break;
case TypeInfo::INT32:
result = builder_.ConvertInt32ToFloat64(gate);
@ -987,7 +1008,14 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType
result = builder_.CheckUndefinedAndConvertToFloat64(gate);
} else {
ASSERT(gateType.IsNumberType());
result = builder_.CheckTaggedNumberAndConvertToFloat64(gate);
if (convert == ConvertToNumber::ALL) {
GateRef glue = acc_.GetGlueFromArgList();
GateRef number = builder_.ToNumber(glue, gate, glue);
ResizeAndSetTypeInfo(number, TypeInfo::TAGGED);
result = builder_.GetDoubleOfTNumber(number);
} else {
result = builder_.CheckTaggedNumberAndConvertToFloat64(gate);
}
}
break;
}
@ -1001,7 +1029,7 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType
return result;
}
GateRef NumberSpeculativeRetype::CheckAndConvertToTagged(GateRef gate, GateType gateType)
GateRef NumberSpeculativeRetype::CheckAndConvertToTagged(GateRef gate, GateType gateType, ConvertToNumber convert)
{
TypeInfo output = GetOutputTypeInfo(gate);
switch (output) {
@ -1019,6 +1047,15 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToTagged(GateRef gate, GateType
return builder_.CheckHoleDoubleAndConvertToTaggedDouble(gate);
case TypeInfo::NONE:
case TypeInfo::TAGGED: {
if (convert == ConvertToNumber::ALL) {
// Convert if not number
ASSERT(gateType.IsNumberType());
GateRef glue = acc_.GetGlueFromArgList();
GateRef ret = builder_.ToNumber(glue, gate, glue);
ResizeAndSetTypeInfo(ret, TypeInfo::TAGGED);
return ret;
}
// Deoptimize if not number
ASSERT(gateType.IsNumberType() || gateType.IsBooleanType());
builder_.TryPrimitiveTypeCheck(gateType, gate);
return gate;
@ -1215,7 +1252,7 @@ GateRef NumberSpeculativeRetype::VisitStoreProperty(GateRef gate)
if (plr.GetRepresentation() == Representation::DOUBLE) {
acc_.SetMetaData(gate, circuit_->StorePropertyNoBarrier());
acc_.ReplaceValueIn(
gate, CheckAndConvertToFloat64(value, GateType::NumberType(), ConvertSupport::DISABLE), 2); // 2: value
gate, CheckAndConvertToFloat64(value, GateType::NumberType(), ConvertToNumber::DISABLE), 2); // 2: value
} else if (plr.GetRepresentation() == Representation::INT) {
acc_.SetMetaData(gate, circuit_->StorePropertyNoBarrier());
acc_.ReplaceValueIn(
@ -1284,22 +1321,35 @@ GateRef NumberSpeculativeRetype::VisitTypeConvert(GateRef gate)
return Circuit::NullGate();
}
GateRef NumberSpeculativeRetype::VisitNumberMod(GateRef gate)
GateRef NumberSpeculativeRetype::VisitMathBuiltin(GateRef gate)
{
if (IsRetype()) {
const PGOSampleType *sampleType = acc_.GetTypedBinaryType(gate).GetPGOSampleType();
if (sampleType->IsNumber()) {
return SetOutputType(gate, *sampleType);
} else {
GateType gateType = acc_.GetGateType(gate);
GateType resType = gateType.IsIntType() ? GateType::IntType() : GateType::DoubleType();
return SetOutputType(gate, resType);
}
} else if (IsConvert()) {
Environment env(gate, circuit_, &builder_);
ConvertForBinaryOp(gate);
return SetOutputType(gate, GateType::DoubleType());
}
ASSERT(IsConvert());
Environment env(gate, circuit_, &builder_);
size_t valueNum = acc_.GetNumValueIn(gate);
for (size_t i = 0; i < valueNum; ++i) {
GateRef input = acc_.GetValueIn(gate, i);
acc_.ReplaceValueIn(gate, CheckAndConvertToFloat64(input, GateType::NumberType(), ConvertToNumber::BOOL_ONLY), i);
}
acc_.ReplaceStateIn(gate, builder_.GetState());
acc_.ReplaceDependIn(gate, builder_.GetDepend());
return Circuit::NullGate();
}
GateRef NumberSpeculativeRetype::VisitMathAbs(GateRef gate)
{
if (IsRetype()) {
return SetOutputType(gate, GateType::NumberType());
}
ASSERT(IsConvert());
Environment env(gate, circuit_, &builder_);
ASSERT(acc_.GetNumValueIn(gate) == 1);
GateRef input = acc_.GetValueIn(gate, 0);
acc_.ReplaceValueIn(gate, CheckAndConvertToTagged(input, GateType::NumberType(), ConvertToNumber::BOOL_ONLY), 0);
acc_.ReplaceStateIn(gate, builder_.GetState());
acc_.ReplaceDependIn(gate, builder_.GetDepend());
return Circuit::NullGate();
}
@ -1369,7 +1419,7 @@ GateRef NumberSpeculativeRetype::VisitMonoStoreProperty(GateRef gate)
if (plr.GetRepresentation() == Representation::DOUBLE) {
acc_.SetStoreNoBarrier(gate, true);
acc_.ReplaceValueIn(
gate, CheckAndConvertToFloat64(value, GateType::NumberType(), ConvertSupport::DISABLE), 4); // 4: value
gate, CheckAndConvertToFloat64(value, GateType::NumberType(), ConvertToNumber::DISABLE), 4); // 4: value
} else if (plr.GetRepresentation() == Representation::INT) {
acc_.SetStoreNoBarrier(gate, true);
acc_.ReplaceValueIn(

View File

@ -45,6 +45,17 @@ private:
SHIFT_AND_LOGICAL,
};
enum class ConvertToNumber {
DISABLE,
BOOL_ONLY,
ALL
};
ConvertSupport ToConvertSupport(ConvertToNumber convert)
{
return convert == ConvertToNumber::DISABLE ? ConvertSupport::DISABLE : ConvertSupport::ENABLE;
}
bool IsRetype() const
{
return state_ == State::Retype;
@ -78,7 +89,8 @@ private:
GateRef VisitNumberCompare(GateRef gate);
GateRef VisitNumberShiftAndLogical(GateRef gate);
GateRef VisitNumberToString(GateRef gate);
GateRef VisitNumberMod(GateRef gate);
GateRef VisitMathBuiltin(GateRef gate);
GateRef VisitMathAbs(GateRef gate);
GateRef VisitBooleanJump(GateRef gate);
GateRef VisitRangeCheckPredicate(GateRef gate);
GateRef VisitIndexCheck(GateRef gate);
@ -112,8 +124,9 @@ private:
GateRef CheckAndConvertToInt32(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE,
OpType type = OpType::NORMAL);
GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE);
GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType);
GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType,
ConvertToNumber convert = ConvertToNumber::BOOL_ONLY);
GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType, ConvertToNumber convert);
GateRef CheckAndConvertToBool(GateRef gate, GateType gateType);
GateRef ConvertToTagged(GateRef gate);
GateRef TryConvertConstant(GateRef gate, bool needInt32);

View File

@ -52,6 +52,7 @@
#include "ecmascript/compiler/type_inference/initialization_analysis.h"
#include "ecmascript/compiler/type_inference/pgo_type_infer.h"
#include "ecmascript/compiler/typed_hcr_lowering.h"
#include "ecmascript/compiler/typed_native_inline_lowering.h"
#include "ecmascript/compiler/value_numbering.h"
#include "ecmascript/compiler/instruction_combine.h"
#include "ecmascript/compiler/verifier.h"
@ -420,19 +421,37 @@ public:
if (!passOptions->EnableTypeLowering()) {
return false;
}
TimeScope timescope("TypeHCRLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
bool enableLog = data->GetLog()->EnableMethodCIRLog();
Chunk chunk(data->GetNativeAreaAllocator());
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
TypedHCRLowering lowering(data->GetCircuit(),
&visitor,
data->GetCompilerConfig(),
data->GetTSManager(),
&chunk,
passOptions->EnableLoweringBuiltin());
visitor.AddPass(&lowering);
visitor.VisitGraph();
visitor.PrintLog("TypedHCRLowering");
{
TimeScope timescope("TypeHCRLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
bool enableLog = data->GetLog()->EnableMethodCIRLog();
Chunk chunk(data->GetNativeAreaAllocator());
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
TypedHCRLowering lowering(data->GetCircuit(),
&visitor,
data->GetCompilerConfig(),
data->GetTSManager(),
&chunk,
passOptions->EnableLoweringBuiltin());
visitor.AddPass(&lowering);
visitor.VisitGraph();
visitor.PrintLog("TypedHCRLowering");
}
{
TimeScope timescope("TypedNativeInlineLoweringPass", data->GetMethodName(), data->GetMethodOffset(),
data->GetLog());
bool enableLog = data->GetLog()->EnableMethodCIRLog();
Chunk chunk(data->GetNativeAreaAllocator());
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
TypedNativeInlineLowering lowering(data->GetCircuit(),
&visitor,
data->GetCompilerConfig(),
&chunk);
visitor.AddPass(&lowering);
visitor.VisitGraph();
visitor.PrintLog("TypedNativeInlineLowering");
}
return true;
}
};

View File

@ -110,6 +110,7 @@ enum class TypedCallTargetCheckOp : uint8_t;
V(NewBuiltinCtorFail2, NEWBUILTINCTORFAIL2) \
V(IsUndefinedOrHole, ISUNDEFINEDORHOLE) \
V(IsNotUndefinedOrHole, ISNOTUNDEFINEDORHOLE) \
V(BuiltinInliningTypeGuard, BUILTIN_INLINING_TYPE_GUARD) \
enum class DeoptType : uint8_t {
NOTCHECK = 0,

View File

@ -521,7 +521,7 @@ void TSInlineLowering::InlineFuncCheck(const InlineTypeInfoAccessor &info)
GateRef frameState = acc_.GetFrameState(gate);
size_t funcIndex = acc_.GetNumValueIn(gate) - 1;
GateRef inlineFunc = acc_.GetValueIn(gate, funcIndex);
// Do not load from inlineFunc beacause type in inlineFunc could be modified by others
// Do not load from inlineFunc because type in inlineFunc could be modified by others
uint32_t methodOffset = info.GetCallMethodId();
GateRef ret = circuit_->NewGate(circuit_->JSInlineTargetTypeCheck(info.GetType()),
MachineType::I1, {callState, callDepend, inlineFunc, builder_.IntPtr(methodOffset), frameState},

View File

@ -1369,8 +1369,11 @@ void TypedBytecodeLowering::LowerTypedSuperCall(GateRef gate)
void TypedBytecodeLowering::SpeculateCallBuiltin(GateRef gate, GateRef func, const std::vector<GateRef> &args,
BuiltinsStubCSigns::ID id, bool isThrow)
{
if (IS_TYPED_INLINE_BUILTINS_ID(id)) {
return;
}
if (!Uncheck()) {
builder_.CallTargetCheck(gate, func, builder_.IntPtr(static_cast<int64_t>(id)), args[0]);
builder_.CallTargetCheck(gate, func, builder_.IntPtr(static_cast<int64_t>(id)), {args[0]});
}
GateRef result = builder_.TypedCallBuiltin(gate, args, id);

View File

@ -0,0 +1,269 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/compiler/typed_native_inline_lowering.h"
#include "ecmascript/compiler/circuit_builder_helper.h"
#include "ecmascript/compiler/circuit_builder-inl.h"
namespace panda::ecmascript::kungfu {
GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
{
auto op = acc_.GetOpCode(gate);
switch (op) {
case OpCode::MATH_COS:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatCos));
break;
case OpCode::MATH_COSH:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatCosh));
break;
case OpCode::MATH_SIN:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatSin));
break;
case OpCode::MATH_LOG:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatLog));
break;
case OpCode::MATH_LOG2:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatLog2));
break;
case OpCode::MATH_LOG10:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatLog10));
break;
case OpCode::MATH_LOG1P:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatLog1p));
break;
case OpCode::MATH_SINH:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatSinh));
break;
case OpCode::MATH_ASINH:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatAsinh));
break;
case OpCode::MATH_TAN:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatTan));
break;
case OpCode::MATH_ATAN:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatAtan));
break;
case OpCode::MATH_TANH:
LowerGeneralUnaryMath(gate, RTSTUB_ID(FloatTanh));
break;
case OpCode::MATH_ACOS:
LowerGeneralUnaryMath<MathTrigonometricCheck::ABS_GT_ONE>(gate, RTSTUB_ID(FloatAcos));
break;
case OpCode::MATH_ASIN:
LowerGeneralUnaryMath<MathTrigonometricCheck::ABS_GT_ONE>(gate, RTSTUB_ID(FloatAsin));
break;
case OpCode::MATH_ATANH:
LowerGeneralUnaryMath<MathTrigonometricCheck::ABS_GT_ONE>(gate, RTSTUB_ID(FloatAtanh));
break;
case OpCode::MATH_ACOSH:
LowerGeneralUnaryMath<MathTrigonometricCheck::LT_ONE>(gate, RTSTUB_ID(FloatAcosh));
break;
case OpCode::MATH_ATAN2:
LowerMathAtan2(gate);
break;
case OpCode::MATH_ABS:
LowerAbs(gate);
break;
case OpCode::MATH_POW:
LowerMathPow(gate);
break;
default:
break;
}
return Circuit::NullGate();
}
void TypedNativeInlineLowering::LowerMathPow(GateRef gate)
{
Environment env(gate, circuit_, &builder_);
GateRef base = acc_.GetValueIn(gate, 0);
GateRef exp = acc_.GetValueIn(gate, 1);
Label exit(&builder_);
Label notNan(&builder_);
auto nanValue = builder_.NanValue();
DEFVALUE(result, (&builder_), VariableType::FLOAT64(), nanValue);
const double doubleOne = 1.0;
GateRef baseIsOne = builder_.DoubleEqual(base, builder_.Double(doubleOne));
// Base is 1.0, exponent is inf => NaN
// Exponent is not finit, if is NaN or is Inf
GateRef tempIsNan = builder_.BoolAnd(baseIsOne, builder_.DoubleIsINF(exp));
GateRef resultIsNan = builder_.BoolOr(builder_.DoubleIsNAN(exp), tempIsNan);
builder_.Branch(resultIsNan, &exit, &notNan);
builder_.Bind(&notNan);
{
GateRef glue = acc_.GetGlueFromArgList();
result = builder_.CallNGCRuntime(glue, RTSTUB_ID(FloatPow), Gate::InvalidGateRef, {base, exp}, gate);
builder_.Jump(&exit);
}
builder_.Bind(&exit);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
}
template <TypedNativeInlineLowering::MathTrigonometricCheck CHECK>
void TypedNativeInlineLowering::LowerGeneralUnaryMath(GateRef gate, RuntimeStubCSigns::ID stubId)
{
Environment env(gate, circuit_, &builder_);
Label exit(&builder_);
Label checkNotPassed(&builder_);
GateRef value = acc_.GetValueIn(gate, 0);
DEFVALUE(result, (&builder_), VariableType::FLOAT64(), builder_.Double(base::NAN_VALUE));
GateRef check;
const double doubleOne = 1.0;
if constexpr (CHECK == TypedNativeInlineLowering::MathTrigonometricCheck::NOT_NAN) {
check = builder_.DoubleIsNAN(value);
} else if constexpr (CHECK == TypedNativeInlineLowering::MathTrigonometricCheck::LT_ONE) {
check = builder_.DoubleLessThan(value, builder_.Double(doubleOne));
} else if constexpr (CHECK == TypedNativeInlineLowering::MathTrigonometricCheck::ABS_GT_ONE) {
auto gt = builder_.DoubleGreaterThan(value, builder_.Double(doubleOne));
auto lt = builder_.DoubleLessThan(value, builder_.Double(-doubleOne));
check = builder_.BoolOr(gt, lt);
}
builder_.Branch(check, &exit, &checkNotPassed);
builder_.Bind(&checkNotPassed);
{
GateRef glue = acc_.GetGlueFromArgList();
result = builder_.CallNGCRuntime(glue, stubId, Gate::InvalidGateRef, {value}, gate);
builder_.Jump(&exit);
}
builder_.Bind(&exit);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
}
void TypedNativeInlineLowering::LowerMathAtan2(GateRef gate)
{
Environment env(gate, circuit_, &builder_);
GateRef y = acc_.GetValueIn(gate, 0);
GateRef x = acc_.GetValueIn(gate, 1);
DEFVALUE(result, (&builder_), VariableType::FLOAT64(), builder_.Double(base::NAN_VALUE));
Label exit(&builder_);
Label label1(&builder_);
Label label2(&builder_);
Label label3(&builder_);
auto yIsNan = builder_.DoubleIsNAN(y);
auto xIsNan = builder_.DoubleIsNAN(x);
auto checkNaN = builder_.BoolOr(yIsNan, xIsNan);
builder_.Branch(checkNaN, &exit, &label1);
builder_.Bind(&label1);
{
Label label4(&builder_);
auto yIsZero = builder_.DoubleEqual(y, builder_.Double(0.));
auto xIsMoreZero = builder_.DoubleGreaterThan(x, builder_.Double(0.));
auto check = builder_.BoolAnd(yIsZero, xIsMoreZero);
builder_.Branch(check, &label4, &label2);
builder_.Bind(&label4);
{
result = y;
builder_.Jump(&exit);
}
}
builder_.Bind(&label2);
{
Label label5(&builder_);
auto xIsPositiveInf = builder_.DoubleEqual(x, builder_.Double(std::numeric_limits<double>::infinity()));
builder_.Branch(xIsPositiveInf, &label5, &label3);
builder_.Bind(&label5);
{
Label label6(&builder_);
Label label7(&builder_);
auto yPositiveCheck = builder_.DoubleGreaterThanOrEqual(y, builder_.Double(0.));
builder_.Branch(yPositiveCheck, &label6, &label7);
builder_.Bind(&label6);
{
result = builder_.Double(0.0);
builder_.Jump(&exit);
}
builder_.Bind(&label7);
{
result = builder_.Double(-0.0);
builder_.Jump(&exit);
}
}
}
builder_.Bind(&label3);
{
GateRef glue = acc_.GetGlueFromArgList();
result = builder_.CallNGCRuntime(glue, RTSTUB_ID(FloatAtan2), Gate::InvalidGateRef, {y, x}, gate);
builder_.Jump(&exit);
}
builder_.Bind(&exit);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
}
// Int abs : The internal representation of an integer is inverse code,
// The absolute value of a negative number can be found by inverting it by adding one.
// Float abs : A floating-point number is composed of mantissa and exponent.
// The length of mantissa will affect the precision of the number, and its sign will determine the sign of the number.
// The absolute value of a floating-point number can be found by setting mantissa sign bit to 0.
void TypedNativeInlineLowering::LowerAbs(GateRef gate)
{
Environment env(gate, circuit_, &builder_);
Label exit(&builder_);
GateRef param = acc_.GetValueIn(gate, 0);
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
Label isInt(&builder_);
Label notInt(&builder_);
Label isIntMin(&builder_);
Label isResultInt(&builder_);
Label intExit(&builder_);
builder_.Branch(builder_.TaggedIsInt(param), &isInt, &notInt);
builder_.Bind(&isInt);
{
auto value = builder_.GetInt32OfTInt(param);
builder_.Branch(builder_.Equal(value, builder_.Int32(INT32_MIN)), &isIntMin, &isResultInt);
builder_.Bind(&isResultInt);
{
auto temp = builder_.Int32ASR(value, builder_.Int32(JSTaggedValue::INT_SIGN_BIT_OFFSET));
auto res = builder_.Int32Xor(value, temp);
result = builder_.Int32ToTaggedPtr(builder_.Int32Sub(res, temp));
builder_.Jump(&intExit);
}
builder_.Bind(&isIntMin);
{
result = builder_.DoubleToTaggedDoublePtr(builder_.Double(-static_cast<double>(INT_MIN)));
builder_.Jump(&intExit);
}
// Aot compiler fails without jump to intermediate label
builder_.Bind(&intExit);
builder_.Jump(&exit);
}
builder_.Bind(&notInt);
{
auto value = builder_.GetDoubleOfTDouble(param);
// set the sign bit to 0 by shift left then right.
auto temp = builder_.Int64LSL(builder_.CastDoubleToInt64(value), builder_.Int64(1));
auto res = builder_.Int64LSR(temp, builder_.Int64(1));
result = builder_.DoubleToTaggedDoublePtr(builder_.CastInt64ToFloat64(res));
builder_.Jump(&exit);
}
builder_.Bind(&exit);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMASCRIPT_COMPILER_TYPED_NATIVE_INLINE_LOWERING_H
#define ECMASCRIPT_COMPILER_TYPED_NATIVE_INLINE_LOWERING_H
#include "ecmascript/compiler/combined_pass_visitor.h"
namespace panda::ecmascript::kungfu {
class TypedNativeInlineLowering : public PassVisitor {
public:
TypedNativeInlineLowering(Circuit* circuit,
RPOVisitor* visitor,
CompilationConfig* cmpCfg,
Chunk* chunk)
: PassVisitor(circuit, chunk, visitor),
circuit_(circuit),
acc_(circuit),
builder_(circuit, cmpCfg) {}
~TypedNativeInlineLowering() = default;
GateRef VisitGate(GateRef gate) override;
private:
enum class MathTrigonometricCheck : uint8_t {
NOT_NAN,
LT_ONE,
ABS_GT_ONE
};
template <MathTrigonometricCheck CHECK = MathTrigonometricCheck::NOT_NAN>
void LowerGeneralUnaryMath(GateRef gate, RuntimeStubCSigns::ID stubId);
void LowerMathAtan2(GateRef gate);
void LowerAbs(GateRef gate);
void LowerMathPow(GateRef gate);
private:
Circuit* circuit_ {nullptr};
GateAccessor acc_;
CircuitBuilder builder_;
};
}
#endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H

View File

@ -152,11 +152,25 @@ class ObjectFactory;
V(JSTaggedValue, EmptyTaggedQueue, EMPTY_TAGGED_QUEUE_OBJECT_INDEX, ecma_roots_special) \
V(JSTaggedValue, UndefinedCompletionRecord, UNDEFINED_COMPLRTION_RECORD_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathSqrtFunction, MATH_SQRT_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathCosFunction, MATH_COS_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathSinFunction, MATH_SIN_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathACosFunction, MATH_ACOS_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathATanFunction, MATH_ATAN_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAbsFunction, MATH_ABS_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAcos, MATH_ACOS_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAcosh, MATH_ACOSH_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAsin, MATH_ASIN_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAsinh, MATH_ASINH_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAtan, MATH_ATAN_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAtan2, MATH_ATAN2_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAtanh, MATH_ATANH_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathCos, MATH_COS_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathCosh, MATH_COSH_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathSin, MATH_SIN_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathSinh, MATH_SINH_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathTan, MATH_TAN_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathTanh, MATH_TANH_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathLog, MATH_LOG_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathLog2, MATH_LOG2_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathLog10, MATH_LOG10_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathLog1p, MATH_LOG1P_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAbs, MATH_ABS_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathPow, MATH_POW_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathFloorFunction, MATH_FLOOR_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, LocaleCompareFunction, LOCALE_COMPARE_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, ArraySortFunction, ARRAY_SORT_FUNCTION_INDEX, ecma_roots_special) \

View File

@ -2883,35 +2883,100 @@ JSTaggedType RuntimeStubs::FloatSqrt(double x)
return JSTaggedValue(result).GetRawData();
}
JSTaggedType RuntimeStubs::FloatCos(double x)
double RuntimeStubs::FloatAcos(double x)
{
double result = std::cos(x);
return JSTaggedValue(result).GetRawData();
return std::acos(x);
}
JSTaggedType RuntimeStubs::FloatSin(double x)
double RuntimeStubs::FloatAcosh(double x)
{
double result = std::sin(x);
return JSTaggedValue(result).GetRawData();
return std::acosh(x);
}
JSTaggedType RuntimeStubs::FloatACos(double x)
double RuntimeStubs::FloatAsin(double x)
{
double result = std::acos(x);
return JSTaggedValue(result).GetRawData();
return std::asin(x);
}
JSTaggedType RuntimeStubs::FloatATan(double x)
double RuntimeStubs::FloatAsinh(double x)
{
double result = std::atan(x);
return JSTaggedValue(result).GetRawData();
return std::asinh(x);
}
JSTaggedType RuntimeStubs::FloatFloor(double x)
double RuntimeStubs::FloatAtan(double x)
{
return std::atan(x);
}
double RuntimeStubs::FloatAtan2(double y, double x)
{
return std::atan2(y, x);
}
double RuntimeStubs::FloatAtanh(double x)
{
return std::atanh(x);
}
double RuntimeStubs::FloatCos(double x)
{
return std::cos(x);
}
double RuntimeStubs::FloatCosh(double x)
{
return std::cosh(x);
}
double RuntimeStubs::FloatSin(double x)
{
return std::sin(x);
}
double RuntimeStubs::FloatSinh(double x)
{
return std::sinh(x);
}
double RuntimeStubs::FloatTan(double x)
{
return std::tan(x);
}
double RuntimeStubs::FloatTanh(double x)
{
return std::tanh(x);
}
double RuntimeStubs::FloatFloor(double x)
{
ASSERT(!std::isnan(x));
double result = std::floor(x);
return JSTaggedValue(result).GetRawData();
return std::floor(x);
}
double RuntimeStubs::FloatLog(double x)
{
return std::log(x);
}
double RuntimeStubs::FloatLog2(double x)
{
return std::log2(x);
}
double RuntimeStubs::FloatLog10(double x)
{
return std::log10(x);
}
double RuntimeStubs::FloatLog1p(double x)
{
return std::log1p(x);
}
double RuntimeStubs::FloatPow(double base, double exp)
{
return std::pow(base, exp);
}
int32_t RuntimeStubs::DoubleToInt(double x, size_t bits)

View File

@ -117,11 +117,25 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
V(DoubleToLength) \
V(FloatMod) \
V(FloatSqrt) \
V(FloatAcos) \
V(FloatAcosh) \
V(FloatAsin) \
V(FloatAsinh) \
V(FloatAtan) \
V(FloatAtan2) \
V(FloatAtanh) \
V(FloatCos) \
V(FloatCosh) \
V(FloatSin) \
V(FloatACos) \
V(FloatATan) \
V(FloatSinh) \
V(FloatTan) \
V(FloatTanh) \
V(FloatLog) \
V(FloatLog2) \
V(FloatLog10) \
V(FloatLog1p) \
V(FloatFloor) \
V(FloatPow) \
V(FindElementWithCache) \
V(TryToElementsIndexOrFindInStringTable) \
V(TryGetInternString) \
@ -463,11 +477,25 @@ public:
static JSTaggedType DoubleToLength(double x);
static double FloatMod(double x, double y);
static JSTaggedType FloatSqrt(double x);
static JSTaggedType FloatCos(double x);
static JSTaggedType FloatSin(double x);
static JSTaggedType FloatACos(double x);
static JSTaggedType FloatATan(double x);
static JSTaggedType FloatFloor(double x);
static double FloatAcos(double x);
static double FloatAcosh(double x);
static double FloatAsin(double x);
static double FloatAsinh(double x);
static double FloatAtan(double x);
static double FloatAtan2(double y, double x);
static double FloatAtanh(double x);
static double FloatCos(double x);
static double FloatCosh(double x);
static double FloatSin(double x);
static double FloatSinh(double x);
static double FloatTan(double x);
static double FloatTanh(double x);
static double FloatFloor(double x);
static double FloatLog(double x);
static double FloatLog2(double x);
static double FloatLog10(double x);
static double FloatLog1p(double x);
static double FloatPow(double base, double exp);
static int32_t FindElementWithCache(uintptr_t argGlue, JSTaggedType hclass,
JSTaggedType key, int32_t num);
static bool StringsAreEquals(EcmaString *str1, EcmaString *str2);

View File

@ -229,7 +229,8 @@ group("ark_aot_ts_test") {
test_list += [ "pgo_call_deopt" ]
}
deps = []
deps = [ "builtin_inlining:ark_aot_builtin_inlining_test" ]
foreach(test, test_list) {
deps += [ "${test}:${test}AotAction" ]
if (!is_debug) {

View File

@ -0,0 +1,17 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
group("ark_aot_builtin_inlining_test") {
testonly = true
deps = [ "math:ark_aot_builtin_inlining_math_test" ]
}

View File

@ -0,0 +1,24 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAbs") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
is_enable_enableArkTools = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare interface ArkTools {
isAOTCompiled(args: any): boolean;
}
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
function doAbs(x: any): number {
return Math.abs(x);
}
function printAbs(x: any) {
try {
print(doAbs(x));
} finally {
}
}
// Check without params
print(Math.abs()); // NaN
// Check with single int param
print(Math.abs(0)); // 0
print(Math.abs(3)); // 3
print(Math.abs(-5)); // 5
// Check with single float param
print(Math.abs(-1.5));
print(Math.abs(Math.PI));
print(Math.abs(-Math.PI));
print(Math.abs(-1.9e80));
print(Math.abs(1.9e80));
print(Math.abs(-1.9e-80));
print(Math.abs(1.9e-80));
// Check with special float params
print(Math.abs(Infinity)); // Infinity
print(Math.abs(-Infinity)); // Infinity
print(Math.abs(NaN)); // NaN
print("1/x: " + 1 / Math.abs(-0));
// Check with 2 params
print(Math.abs(3, 0)); // 3
// Check with 3 params
print(Math.abs(-3, 0, 0)); // 3
// Check with 4 params
print(Math.abs(4, 0, 0, 0)); // 4
// Check with 5 params
print(Math.abs(-4, 0, 0, 0, 0)); // 4
// Replace standard builtin
let true_abs = Math.abs
Math.abs = replace
print(Math.abs(-1.001)); // -1.001, no deopt
Math.abs = true_abs
// Check edge cases
const INT_MAX: number = 2147483647;
const INT_MIN: number = -INT_MAX - 1;
print(Math.abs(INT_MAX)); // INT_MAX
print(Math.abs(2147483648)); // INT_MAX + 1
print(Math.abs(-INT_MAX)); // INT_MAX
print(Math.abs(INT_MIN)); // -INT_MIN
print(Math.abs(INT_MIN - 1)); // -INT_MIN + 1
printAbs(-3);
printAbs("abc");
printAbs("abc");
printAbs(-12); // 12
// Call standard builtin with non-number param
printAbs("abc"); // NaN
printAbs("-12"); // 12
if (ArkTools.isAOTCompiled(printAbs)) {
// Replace standard builtin after call to standard builtin was profiled
Math.abs = replace
}
printAbs(-12); // 12; or -12, deopt
printAbs("abc"); // NaN; or abc, deopt
Math.abs = true_abs
// Check IR correctness inside try-block
try {
printAbs(-12); // 12
printAbs("abc"); // NaN
} catch (e) {
}
let obj = {};
obj.valueOf = (() => { return -23; })
print(Math.abs(obj)); // 23
function Throwing() {
this.value = -14;
}
Throwing.prototype.valueOf = function() {
if (this.value > 0) {
throw new Error("already positive");
}
return this.value;
}
let throwingObj = new Throwing();
try {
print(Math.abs(throwingObj)); // 14
throwingObj.value = 10;
print(Math.abs(throwingObj)); // exception
} catch(e) {
print(e);
} finally {
print(Math.abs(obj)); // 23
}

View File

@ -0,0 +1,60 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
0
3
5
1.5
3.141592653589793
3.141592653589793
1.9e+80
1.9e+80
1.9e-80
1.9e-80
Infinity
Infinity
NaN
1/x: Infinity
3
3
4
4
-1.001
2147483647
2147483648
2147483647
2147483648
2147483649
3
[trace] Check Type: NotNumber2
NaN
[trace] Check Type: NotNumber2
NaN
12
[trace] Check Type: NotNumber2
NaN
[trace] Check Type: NotNumber2
12
[trace] Check Type: NotCallTarget1
-12
[trace] Check Type: NotCallTarget1
abc
12
[trace] Check Type: NotNumber2
NaN
[trace] Check Type: NotNumber2
23
14
Error: already positive
23

View File

@ -0,0 +1,52 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
0
3
5
1.5
3.141592653589793
3.141592653589793
1.9e+80
1.9e+80
1.9e-80
1.9e-80
Infinity
Infinity
NaN
1/x: Infinity
3
3
4
4
-1.001
2147483647
2147483648
2147483647
2147483648
2147483649
3
NaN
NaN
12
NaN
12
12
NaN
12
NaN
23
14
Error: already positive
23

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAcos") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.acos();
print(len); // NaN
len = Math.acos(NaN);
print(len); // NaN
// Check with single param, in |x| <= 1
len = Math.acos(0);
print(len); // PI / 2 = 1.5707963267948966
// Check with single param, in |x| <= 1
len = Math.acos(-1);
print(len); // PI = 3.141592653589793
// Check with single param, in |x| <= 1
len = Math.acos(1);
print(len); // 0
// Check with single param, in |x| > 1
len = Math.acos(10);
print(len); // Nan
// Replace standart builtin
let true_acos = Math.acos
Math.acos = replace
len = Math.acos(111);
print(len);
// Call standart builtin with non-number param
Math.acos = true_acos
len = Math.acos("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
1.5707963267948966
3.141592653589793
0
NaN
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
1.5707963267948966
3.141592653589793
0
NaN
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAcosh") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.acosh();
print(len); // NaN
len = Math.acosh(NaN);
print(len); // NaN
// Check with single param, in x < 1
len = Math.acosh(0);
print(len); // NaN
// Check with single param, in x < 1
len = Math.acosh(-1);
print(len); // NaN
// Check with single param, in x >= 1
len = Math.acosh(1);
print(len); // NaN
// Check with single param, in x >= 1
len = Math.acosh(10);
print(len); // 2.993222846126381
// Replace standart builtin
let true_acosh = Math.acosh
Math.acosh = replace
len = Math.acosh(111);
print(len);
// Call standart builtin with non-number param
Math.acosh = true_acosh
len = Math.acosh("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
NaN
NaN
0
2.993222846126381
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
NaN
NaN
0
2.993222846126381
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAsin") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.asin();
print(len); // NaN
len = Math.asin(NaN);
print(len); // NaN
// Check with single param, in |x| <= 1
len = Math.asin(0);
print(len); // 0
// Check with single param, in |x| <= 1
len = Math.asin(-1);
print(len); // - PI / 2 = - 1.5707963267948966
// Check with single param, in |x| <= 1
len = Math.asin(1);
print(len); // PI / 2 = 1.5707963267948966
// Check with single param, in |x| > 1
len = Math.asin(10);
print(len); // Nan
// Replace standart builtin
let true_asin = Math.asin
Math.asin = replace
len = Math.asin(111);
print(len);
// Call standart builtin with non-number param
Math.asin = true_asin
len = Math.asin("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-1.5707963267948966
1.5707963267948966
NaN
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-1.5707963267948966
1.5707963267948966
NaN
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAsinh") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.asinh();
print(len); // NaN
len = Math.asinh(NaN);
print(len); // NaN
// Check with single param
len = Math.asinh(0);
print(len); // 0
// Check with single param
len = Math.asinh(-1);
print(len); // -0.881373587019543
// Check with single param
len = Math.asinh(1);
print(len); // 0.881373587019543
// Check with single param
len = Math.asinh(10);
print(len); // 2.99822295029797
// Replace standart builtin
let true_asinh = Math.asinh
Math.asinh = replace
len = Math.asinh(111);
print(len);
// Call standart builtin with non-number param
Math.asinh = true_asinh
len = Math.asinh("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-0.881373587019543
0.881373587019543
2.99822295029797
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-0.881373587019543
0.881373587019543
2.99822295029797
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAtan") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.atan();
print(len); // NaN
len = Math.atan(NaN);
print(len); // NaN
// Check with single param
len = Math.atan(0);
print(len); // 0
// Check with single param
len = Math.atan(-1);
print(len); //-0.7853981633974483
// Check with single param
len = Math.atan(1);
print(len); // 0.7853981633974483
// Check with single param, in |x| > 1
len = Math.atan(10);
print(len); // 1.4711276743037347
// Replace standart builtin
let true_atan = Math.atan
Math.atan = replace
len = Math.atan(111);
print(len);
// Call standart builtin with non-number param
Math.atan = true_atan
len = Math.atan("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-0.7853981633974483
0.7853981633974483
1.4711276743037347
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-0.7853981633974483
0.7853981633974483
1.4711276743037347
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAtan2") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.atan2();
print(len); // NaN
len = Math.atan2(NaN);
print(len); // NaN
len = Math.atan2(NaN, NaN);
print(len); // NaN
len = Math.atan2(0, NaN);
print(len); // NaN
len = Math.atan2(NaN, 0);
print(len); // NaN
len = Math.atan2(-1, 1.5);
print(len); // -0.5880026035475675
len = Math.atan2(1, -0);
print(len); // Math.PI / 2
len = Math.atan2(0, 1);
print(len); // 0
len = Math.atan2(0, -0);
print(len); // Math.PI
len = Math.atan2(-0, 0);
print(len); // -0.
len = Math.atan2(-0, -0);
print(len); // -Math.PI
len = Math.atan2(-1, Number.POSITIVE_INFINITY)
print(len) // -0. !!!! NOTE: now it's return 0, need investigate
len = Math.atan2(1, Number.POSITIVE_INFINITY)
print(len) // 0.
// Replace standart builtin
let true_atan2 = Math.atan2
Math.atan2 = replace
len = Math.atan2(111);
print(len);
// Call standart builtin with non-number param
Math.atan2 = true_atan2
len = Math.atan2(0, "NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,29 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
NaN
NaN
NaN
-0.5880026035475675
1.5707963267948966
0
3.141592653589793
0
-3.141592653589793
0
0
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,28 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
NaN
NaN
NaN
-0.5880026035475675
1.5707963267948966
0
3.141592653589793
0
-3.141592653589793
0
0
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathAtanh") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.atanh();
print(len); // NaN
len = Math.atanh(NaN);
print(len); // NaN
// Check with single param
len = Math.atanh(0);
print(len); // 0
// Check with single param
len = Math.atanh(0.5);
print(len); // 0.5493061443340548
// Check with single param
len = Math.atanh(-1);
print(len); // -Infinity
// Check with single param
len = Math.atanh(1);
print(len); // Infinity
// Check with single param
len = Math.atanh(10);
print(len); // NaN
// Replace standart builtin
let true_atanh = Math.atanh
Math.atanh = replace
len = Math.atanh(111);
print(len);
// Call standart builtin with non-number param
Math.atanh = true_atanh
len = Math.atanh("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
0.5493061443340548
-Infinity
Infinity
NaN
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
0.5493061443340548
-Infinity
Infinity
NaN
111
NaN

View File

@ -0,0 +1,45 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
group("ark_aot_builtin_inlining_math_test") {
testonly = true
test_list = [
"Acos",
"Acosh",
"Asin",
"Asinh",
"Atan",
"Atan2",
"Atanh",
"Cos",
"Cosh",
"Log",
"Log2",
"Log10",
"Log1p",
"Sin",
"Sinh",
"Tan",
"Tanh",
"Abs",
"Pow",
]
deps = []
foreach(test, test_list) {
deps += [ "${test}:builtinMath${test}AotAction" ]
if (!is_debug) {
deps += [ "${test}:builtinMath${test}AotContextAction" ]
}
}
}

View File

@ -0,0 +1,24 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathCos") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
is_test_llvm_only = true
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.cos();
print(len); // Nan
// Check with single param
len = Math.cos(0);
print(len); // 1
// Check with single not zero param
len = Math.cos(Math.PI / 2);
print(len); // 6.123233995736766e-17
// Check with 2 params
len = Math.cos(0, 0);
print(len); // 1
// Check with 3 params
len = Math.cos(0, 0, 0);
print(len); // 1
// Check with 4 params
len = Math.cos(0, 0, 0, 0);
print(len); // 1
// Check with 5 params
len = Math.cos(0, 0, 0, 0, 0);
print(len); // 1
try {
print(Math.cos(0))
} catch(e) {}
// Replace standart builtin
let true_cos = Math.cos
Math.cos = replace
len = Math.cos(111);
print(len); // 111
// Call standart builtin with non-number param
Math.cos = true_cos
len = Math.cos("0");
print(len); // 1
len = Math.cos("0.5");
print(len); // 1

View File

@ -0,0 +1,25 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
1
6.123233995736766e-17
1
1
1
1
1
111
[trace] Check Type: NotNumber1
1
0.8775825618903728

View File

@ -0,0 +1,24 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
1
6.123233995736766e-17
1
1
1
1
1
111
1
0.8775825618903728

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathCosh") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.cosh();
print(len); // NaN
len = Math.cosh(NaN);
print(len); // NaN
// Check with single param
len = Math.cosh(0);
print(len); // 1
// Check with single param
len = Math.cosh(-1);
print(len); // 1.5430806348152437
// Check with single param
len = Math.cosh(1);
print(len); // 1.5430806348152437
// Check with single param
len = Math.cosh(10);
print(len); // 11013.232920103324
// Replace standart builtin
let true_cosh = Math.cosh
Math.cosh = replace
len = Math.cosh(111);
print(len);
// Call standart builtin with non-number param
Math.cosh = true_cosh
len = Math.cosh("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
1
1.5430806348152437
1.5430806348152437
11013.232920103324
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
1
1.5430806348152437
1.5430806348152437
11013.232920103324
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathLog") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let res:number = 0;
// Check without params
res = Math.log();
print(res); // NaN
// Check with single param
res = Math.log(-0);
print(res); // -Infinity
res = Math.log(+0);
print(res); // -Infinity
res = Math.log(-123);
print(res); // NaN
res = Math.log(Math.E);
print(res); // 1
// Check with 2 params
res = Math.log(Math.E, Math.E);
print(res); // 1
// Check with 3 params
res = Math.log(Math.E, Math.E, Math.E);
print(res); // 1
// Check with 4 params
res = Math.log(Math.E, Math.E, Math.E, Math.E);
print(res); // 1
// Check with 5 params
res = Math.log(Math.E, Math.E, Math.E, Math.E, Math.E);
print(res); // 1
try {
print(Math.log(Math.E)); // 1
} catch(e) {}
// Replace standart builtin
let true_log = Math.log
Math.log = replace
res = Math.log(111);
print(res); // 111
// Call standart builtin with non-number param
Math.log = true_log
res = Math.log("-0"); // deopt
print(res); // -Infinity

View File

@ -0,0 +1,26 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
-Infinity
NaN
1
1
1
1
1
1
111
[trace] Check Type: NotNumber1
-Infinity

View File

@ -0,0 +1,25 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
-Infinity
NaN
1
1
1
1
1
1
111
-Infinity

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathLog10") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let res:number = 0;
// Check without params
res = Math.log10();
print(res); // NaN
// Check with single param
res = Math.log10(-0);
print(res); // -Infinity
res = Math.log10(+0);
print(res); // -Infinity
res = Math.log10(-123);
print(res); // NaN
res = Math.log10(10);
print(res); // 1
// Check with 2 params
res = Math.log10(10, 10);
print(res); // 1
// Check with 3 params
res = Math.log10(10, 10, 10);
print(res); // 1
// Check with 4 params
res = Math.log10(10, 10, 10, 10);
print(res); // 1
// Check with 5 params
res = Math.log10(10, 10, 10, 10, 10);
print(res); // 1
try {
print(Math.log10(10)); // 1
} catch(e) {}
// Replace standart builtin
let true_log10 = Math.log10
Math.log10 = replace
res = Math.log10(111);
print(res); // 111
// Call standart builtin with non-number param
Math.log10 = true_log10
res = Math.log10("-0"); // deopt
print(res); // -Infinity

View File

@ -0,0 +1,26 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
-Infinity
NaN
1
1
1
1
1
1
111
[trace] Check Type: NotNumber1
-Infinity

View File

@ -0,0 +1,25 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
-Infinity
NaN
1
1
1
1
1
1
111
-Infinity

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathLog1p") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let res:number = 0;
// Check without params
res = Math.log1p();
print(res); // NaN
// Check with single param
res = Math.log1p(-1);
print(res); // -Infinity
res = Math.log1p(-0);
print(res); // -0
res = Math.log1p(+0);
print(res); // 0
res = Math.log1p(-123);
print(res); // NaN
res = Math.log1p(Math.E - 1);
print(res); // 1
// Check with 2 params
res = Math.log1p(Math.E - 1, Math.E - 1);
print(res); // 1
// Check with 3 params
res = Math.log1p(Math.E - 1, Math.E - 1, Math.E - 1);
print(res); // 1
// Check with 4 params
res = Math.log1p(Math.E - 1, Math.E - 1, Math.E - 1, Math.E - 1);
print(res); // 1
// Check with 5 params
res = Math.log1p(Math.E - 1, Math.E - 1, Math.E - 1, Math.E - 1, Math.E - 1);
print(res); // 1
try {
print(Math.log1p(Math.E - 1)); // 1
} catch(e) {}
// Replace standart builtin
let true_log1p = Math.log1p
Math.log1p = replace
res = Math.log1p(111);
print(res); // 111
// Call standart builtin with non-number param
Math.log1p = true_log1p
res = Math.log1p("-1"); // deopt
print(res); // -Infinity

View File

@ -0,0 +1,27 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
0
0
NaN
1
1
1
1
1
1
111
[trace] Check Type: NotNumber1
-Infinity

View File

@ -0,0 +1,26 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
0
0
NaN
1
1
1
1
1
1
111
-Infinity

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathLog2") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let res:number = 0;
// Check without params
res = Math.log2();
print(res); // NaN
// Check with single param
res = Math.log2(-0);
print(res); // -Infinity
res = Math.log2(+0);
print(res); // -Infinity
res = Math.log2(-123);
print(res); // NaN
res = Math.log2(2);
print(res); // 1
// Check with 2 params
res = Math.log2(2, 2);
print(res); // 1
// Check with 3 params
res = Math.log2(2, 2, 2);
print(res); // 1
// Check with 4 params
res = Math.log2(2, 2, 2, 2);
print(res); // 1
// Check with 5 params
res = Math.log2(2, 2, 2, 2, 2);
print(res); // 1
try {
print(Math.log2(2)); // 1
} catch(e) {}
// Replace standart builtin
let true_log2 = Math.log2
Math.log2 = replace
res = Math.log2(111);
print(res); // 111
// Call standart builtin with non-number param
Math.log2 = true_log2
res = Math.log2("-0"); // deopt
print(res); // -Infinity

View File

@ -0,0 +1,26 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
-Infinity
NaN
1
1
1
1
1
1
111
[trace] Check Type: NotNumber1
-Infinity

View File

@ -0,0 +1,25 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
-Infinity
-Infinity
NaN
1
1
1
1
1
1
111
-Infinity

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathPow") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
let len:number = 1;
// Check without params
len = Math.pow();
print(len); // Nan
// Check with single param
len = Math.pow(0);
print(len); // Nan
// Check with three param
len = Math.pow(2, 4, 6);
print(len); // 16
// If exponent is NaN, return NaN.
len = Math.pow(2, NaN)
print(len) // NaN
// If exponent is either +0.0 or -0.0, return 1.0
len = Math.pow(3, +0.0);
print(len); // 1
let temp = -0.0
len = Math.pow(3, -0.0);
print(len); // 1
// If base is -inf, then:
// a. If exponent > +0.0, then
// * If exponent is an odd integral Number, return -inf. Otherwise, return +inf.
len = Math.pow(-Infinity, 5);
print(len); // -Infinity
len = Math.pow(-Infinity, 6);
print(len); // Infinity
// b. Else:
// * If exponent is an odd integral Number, return -0.0. Otherwise, return +0.0.
len = Math.pow(-Infinity, -3);
print(len); // -0.0
len = Math.pow(-Infinity, -4);
print(len); // +0.0
// If base is +0.0 and if exponent > +0.0, return +0.0. Otherwise, return +inf.
len = Math.pow(+0.0, 2);
print(len); // +0.0
len = Math.pow(+0.0, -2);
print(len); // +inf
// If base is -0.0, then
// a. If exponent > +0.0, then
// * If exponent is an odd integral Number, return -0.0. Otherwise, return +0.0.
len = Math.pow(-0.0, 7);
print(len); // -0.0
len = Math.pow(-0.0, 8);
print(len); // +0.0
// b. Else,
// * If exponent is an odd integral Number, return -inf. Otherwise, return +inf.
len = Math.pow(-0.0, -9);
print(len); // -inf
len = Math.pow(-0.0, -10);
print(len); // +inf
// If exponent is +inf, then
// a. If abs(base) > 1, return +inf.
len = Math.pow(1.5, +Infinity);
print(len); // +inf
// b. If abs(base) = 1, return NaN.
len = Math.pow(1, +Infinity);
print(len); // NaN
// c. If abs(base) < 1, return +inf.
len = Math.pow(0.5, +Infinity);
print(len); // +0.0
// If exponent is -inf, then
// a. If abs(base) > 1, return +inf.
len = Math.pow(1.5, -Infinity);
print(len); // +0.0
// b. If abs(base) = 1, return NaN.
len = Math.pow(1, -Infinity);
print(len); // NaN
// c. If abs(base) < 1, return +inf.
len = Math.pow(0.2, -Infinity);
print(len); // +inf
len = Math.pow(2, "three");
print(len); // Nan

View File

@ -0,0 +1,37 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
16
NaN
1
1
-Infinity
Infinity
0
0
0
Infinity
0
0
-Infinity
Infinity
Infinity
NaN
0
0
NaN
Infinity
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,36 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
16
NaN
1
1
-Infinity
Infinity
0
0
0
Infinity
0
0
-Infinity
Infinity
Infinity
NaN
0
0
NaN
Infinity
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathSin") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.sin();
print(len); // Nan
// Check with single param
len = Math.sin(0);
print(len); // 0
// Check with single not zero param
len = Math.sin(Math.PI / 2);
print(len); // 1
// Check with 2 params
len = Math.sin(0,0);
print(len); // 0
// Check with 3 params
len = Math.sin(0,0,0);
print(len); // 0
// Check with 4 params
len = Math.sin(0,0,0,0);
print(len); // 0
// Check with 5 params
len = Math.sin(0,0,0,0,0);
print(len); // 0
// Replace standart builtin
let true_sin = Math.sin
Math.sin = replace
len = Math.sin(111);
print(len); // 111
// Call standart builtin with non-number param
Math.sin = true_sin
len = Math.sin("0"); // deopt
print(len); // 0

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
0
1
0
0
0
0
111
[trace] Check Type: NotNumber1
0

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
0
1
0
0
0
0
111
0

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathSinh") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
// Check without params
len = Math.sinh();
print(len); // NaN
len = Math.sinh(NaN);
print(len); // NaN
// Check with single param
len = Math.sinh(0);
print(len); // 0
// Check with single param
len = Math.sinh(-1);
print(len); // -1.1752011936438014
// Check with single param
len = Math.sinh(1);
print(len); // 1.1752011936438014
// Check with single param
len = Math.sinh(10);
print(len); // 11013.232874703393
// Replace standart builtin
let true_sinh = Math.sinh
Math.sinh = replace
len = Math.sinh(111);
print(len);
// Call standart builtin with non-number param
Math.sinh = true_sinh
len = Math.sinh("NaN"); // deopt
print(len); // NaN

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-1.1752011936438014
1.1752011936438014
11013.232874703393
111
[trace] Check Type: NotNumber1
NaN

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
NaN
NaN
0
-1.1752011936438014
1.1752011936438014
11013.232874703393
111
NaN

View File

@ -0,0 +1,23 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtinMathTan") {
is_enable_pgo = true
is_only_typed_path = true
is_enable_opt_inlining = true
is_enable_trace_deopt = true
log_option = " --log-info=trace"
deps = []
}

Some files were not shown because too many files have changed in this diff Show More