mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-04-02 07:52:43 +00:00
!7018 Devbranch for DateNow, BigInt, Map, Set, TypedArray
Merge pull request !7018 from Ishin Pavel/dev_branch_map_set
This commit is contained in:
commit
1c77da3d0e
@ -806,13 +806,16 @@ void Builtins::InitializeBigInt(const JSHandle<GlobalEnv> &env, const JSHandle<J
|
||||
bigIntFuncInstanceHClass.GetTaggedValue());
|
||||
|
||||
// BigInt.prototype method
|
||||
SetFunction(env, bigIntFuncPrototype, "toLocaleString", BuiltinsBigInt::ToLocaleString, FunctionLength::ZERO);
|
||||
SetFunction(env, bigIntFuncPrototype, "toString", BuiltinsBigInt::ToString, FunctionLength::ZERO);
|
||||
SetFunction(env, bigIntFuncPrototype, "valueOf", BuiltinsBigInt::ValueOf, FunctionLength::ZERO);
|
||||
for (const auto &entry : BuiltinsBigInt::GetBigIntPrototypeFunctions()) {
|
||||
SetFunction(env, bigIntFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
|
||||
entry.GetLength(), entry.GetBuiltinStubId());
|
||||
}
|
||||
|
||||
// BigInt method
|
||||
SetFunction(env, bigIntFunction, "asUintN", BuiltinsBigInt::AsUintN, FunctionLength::TWO);
|
||||
SetFunction(env, bigIntFunction, "asIntN", BuiltinsBigInt::AsIntN, FunctionLength::TWO);
|
||||
for (const auto &entry : BuiltinsBigInt::GetBigIntFunctions()) {
|
||||
SetFunction(env, bigIntFunction, entry.GetName(), entry.GetEntrypoint(),
|
||||
entry.GetLength(), entry.GetBuiltinStubId());
|
||||
}
|
||||
|
||||
// @@ToStringTag
|
||||
SetStringTagSymbol(env, bigIntFuncPrototype, "BigInt");
|
||||
@ -1291,7 +1294,7 @@ void Builtins::LazyInitializeSet(const JSHandle<GlobalEnv> &env)
|
||||
void Builtins::InitializeMap(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
|
||||
auto *globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
|
||||
// Map.prototype
|
||||
JSHandle<JSHClass> mapFuncPrototypeHClass = factory_->NewEcmaHClass(
|
||||
JSObject::SIZE, BuiltinsMap::GetNumPrototypeInlinedProperties(), JSType::JS_OBJECT, objFuncPrototypeVal);
|
||||
@ -1300,6 +1303,9 @@ void Builtins::InitializeMap(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedVa
|
||||
// Map.prototype_or_hclass
|
||||
JSHandle<JSHClass> mapFuncInstanceHClass =
|
||||
factory_->NewEcmaHClass(JSMap::SIZE, JSType::JS_MAP, mapFuncPrototypeValue);
|
||||
|
||||
globalConst->SetConstant(ConstantIndex::JS_MAP_HCLASS_INDEX, mapFuncInstanceHClass);
|
||||
|
||||
// Map() = new Function()
|
||||
JSHandle<JSTaggedValue> mapFunction(
|
||||
NewBuiltinConstructor(env, mapFuncPrototype, BuiltinsMap::MapConstructor, "Map", FunctionLength::ZERO,
|
||||
|
@ -19,15 +19,36 @@
|
||||
#include "ecmascript/base/builtins_base.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
|
||||
// List of functions in BigInt, excluding the constructor and '@@' properties.
|
||||
// V(name, func, length, stubIndex)
|
||||
// where BuiltinsBigInt::func refers to the native implementation of BigInt[name].
|
||||
// kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
|
||||
#define BUILTIN_BIGINT_FUNCTIONS(V) \
|
||||
/* BigInt.asIntN (bits, bigint) */ \
|
||||
V("asIntN", AsIntN, 2, BigIntAsIntN) \
|
||||
/* BigInt.asUintN ( bits, bigint ) */ \
|
||||
V("asUintN", AsUintN, 2, BigIntAsUintN)
|
||||
// List of functions in BigInt.prototype, excluding the constructor and '@@' properties.
|
||||
// V(name, func, length, stubIndex)
|
||||
// where BuiltinsBigInt::func refers to the native implementation of BigInt.prototype[name].
|
||||
// kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
|
||||
#define BUILTIN_BIGINT_PROTOTYPE_FUNCTIONS(V) \
|
||||
/* BigInt.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) */ \
|
||||
V("toLocaleString", ToLocaleString, 0, INVALID) \
|
||||
/* BigInt.toString ( [radix] ) */ \
|
||||
V("toString", ToString, 0, INVALID) \
|
||||
/* BigInt.valueOf ( ) */ \
|
||||
V("valueOf", ValueOf, 0, INVALID)
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
class BuiltinsBigInt : public base::BuiltinsBase {
|
||||
public:
|
||||
// 21.2.1.1
|
||||
static JSTaggedValue BigIntConstructor(EcmaRuntimeCallInfo *argv);
|
||||
// 21.2.2.1
|
||||
static JSTaggedValue AsUintN(EcmaRuntimeCallInfo *argv);
|
||||
// 21.2.2.2
|
||||
static JSTaggedValue AsIntN(EcmaRuntimeCallInfo *argv);
|
||||
// 21.2.2.2
|
||||
static JSTaggedValue AsUintN(EcmaRuntimeCallInfo *argv);
|
||||
// 21.2.3.2
|
||||
static JSTaggedValue ToLocaleString(EcmaRuntimeCallInfo *argv);
|
||||
// 21.2.3.3
|
||||
@ -36,6 +57,31 @@ public:
|
||||
static JSTaggedValue ValueOf(EcmaRuntimeCallInfo *argv);
|
||||
private:
|
||||
static JSTaggedValue ThisBigIntValue(EcmaRuntimeCallInfo *argv);
|
||||
|
||||
public:
|
||||
// Excluding the constructor and '@@' internal properties.
|
||||
static Span<const base::BuiltinFunctionEntry> GetBigIntFunctions()
|
||||
{
|
||||
return Span<const base::BuiltinFunctionEntry>(BIGINT_FUNCTIONS);
|
||||
}
|
||||
|
||||
// Excluding the constructor and '@@' internal properties.
|
||||
static Span<const base::BuiltinFunctionEntry> GetBigIntPrototypeFunctions()
|
||||
{
|
||||
return Span<const base::BuiltinFunctionEntry>(BIGINT_PROTOTYPE_FUNCTIONS);
|
||||
}
|
||||
|
||||
private:
|
||||
#define BUILTIN_BIGINT_FUNCTION_ENTRY(name, func, length, builtinId) \
|
||||
base::BuiltinFunctionEntry::Create(name, BuiltinsBigInt::func, length, kungfu::BuiltinsStubCSigns::builtinId),
|
||||
|
||||
static inline std::array BIGINT_FUNCTIONS = {
|
||||
BUILTIN_BIGINT_FUNCTIONS(BUILTIN_BIGINT_FUNCTION_ENTRY)
|
||||
};
|
||||
static inline std::array BIGINT_PROTOTYPE_FUNCTIONS = {
|
||||
BUILTIN_BIGINT_PROTOTYPE_FUNCTIONS(BUILTIN_BIGINT_FUNCTION_ENTRY)
|
||||
};
|
||||
#undef BUILTIN_BIGINT_FUNCTION_ENTRY
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
#endif // ECMASCRIPT_BUILTINS_BUILTINS_BIGINT_H
|
@ -25,7 +25,7 @@
|
||||
// kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
|
||||
#define BUILTIN_DATE_FUNCTIONS(V) \
|
||||
/* Date.now ( ) */ \
|
||||
V("now", Now, 0, INVALID) \
|
||||
V("now", Now, 0, DateNow) \
|
||||
/* Date.parse ( string ) */ \
|
||||
V("parse", Parse, 1, INVALID) \
|
||||
/* Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ) */ \
|
||||
|
@ -76,7 +76,7 @@
|
||||
/* %TypedArray%.prototype.copyWithin ( target, start [ , end ] ) */ \
|
||||
V("copyWithin", CopyWithin, 2, TypedArrayCopyWithin) \
|
||||
/* %TypedArray%.prototype.entries ( ) */ \
|
||||
V("entries", Entries, 0, INVALID) \
|
||||
V("entries", Entries, 0, TypedArrayEntries) \
|
||||
/* %TypedArray%.prototype.every ( callbackfn [ , thisArg ] ) */ \
|
||||
V("every", Every, 1, TypedArrayEvery) \
|
||||
/* %TypedArray%.prototype.fill ( value [ , start [ , end ] ] ) */ \
|
||||
@ -100,7 +100,7 @@
|
||||
/* %TypedArray%.prototype.join ( separator ) */ \
|
||||
V("join", Join, 1, INVALID) \
|
||||
/* %TypedArray%.prototype.keys ( ) */ \
|
||||
V("keys", Keys, 0, INVALID) \
|
||||
V("keys", Keys, 0, TypedArrayKeys) \
|
||||
/* %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] ) */ \
|
||||
V("lastIndexOf", LastIndexOf, 1, TypedArrayLastIndexOf) \
|
||||
/* %TypedArray%.prototype.map ( callbackfn [ , thisArg ] ) */ \
|
||||
@ -128,7 +128,7 @@
|
||||
/* %TypedArray%.prototype.toSorted ( comparefn ) */ \
|
||||
V("toSorted", ToSorted, 1, INVALID) \
|
||||
/* %TypedArray%.prototype.values ( ) */ \
|
||||
V("values", Values, 0, INVALID) \
|
||||
V("values", Values, 0, TypedArrayValues) \
|
||||
/* %TypedArray%.prototype.with ( index, value ) */ \
|
||||
V("with", With, 2, TypedArrayWith)
|
||||
|
||||
|
@ -139,6 +139,9 @@ namespace panda::ecmascript::kungfu {
|
||||
V(Some, TypedArray, Undefined()) \
|
||||
V(Filter, TypedArray, Undefined()) \
|
||||
V(With, TypedArray, Undefined()) \
|
||||
V(Entries, TypedArray, Undefined()) \
|
||||
V(Keys, TypedArray, Undefined()) \
|
||||
V(Values, TypedArray, Undefined()) \
|
||||
V(Slice, TypedArray, Undefined()) \
|
||||
V(SubArray, TypedArray, Undefined()) \
|
||||
V(Sort, TypedArray, Undefined()) \
|
||||
@ -232,9 +235,12 @@ namespace panda::ecmascript::kungfu {
|
||||
V(MathMax) \
|
||||
V(MathImul) \
|
||||
V(DateGetTime) \
|
||||
V(DateNow) \
|
||||
V(GlobalIsFinite) \
|
||||
V(GlobalIsNan) \
|
||||
V(ArrayBufferIsView) \
|
||||
V(BigIntAsIntN) \
|
||||
V(BigIntAsUintN) \
|
||||
V(DataViewGetFloat32) \
|
||||
V(DataViewGetFloat64) \
|
||||
V(DataViewGetInt8) \
|
||||
@ -329,6 +335,11 @@ public:
|
||||
case BuiltinsStubCSigns::ID::MapGet:
|
||||
case BuiltinsStubCSigns::ID::MapHas:
|
||||
case BuiltinsStubCSigns::ID::SetHas:
|
||||
case BuiltinsStubCSigns::ID::MapDelete:
|
||||
case BuiltinsStubCSigns::ID::SetDelete:
|
||||
case BuiltinsStubCSigns::ID::TypedArrayEntries:
|
||||
case BuiltinsStubCSigns::ID::TypedArrayKeys:
|
||||
case BuiltinsStubCSigns::ID::TypedArrayValues:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -451,6 +462,10 @@ public:
|
||||
return ConstantIndex::MAP_HAS_INDEX;
|
||||
case BuiltinsStubCSigns::ID::SetHas:
|
||||
return ConstantIndex::SET_HAS_INDEX;
|
||||
case BuiltinsStubCSigns::ID::MapDelete:
|
||||
return ConstantIndex::MAP_DELETE_INDEX;
|
||||
case BuiltinsStubCSigns::ID::SetDelete:
|
||||
return ConstantIndex::SET_DELETE_INDEX;
|
||||
case BuiltinsStubCSigns::ID::StringLocaleCompare:
|
||||
return ConstantIndex::LOCALE_COMPARE_FUNCTION_INDEX;
|
||||
case BuiltinsStubCSigns::ID::ArraySort:
|
||||
@ -471,6 +486,14 @@ public:
|
||||
return ConstantIndex::STRING_FROM_CHAR_CODE_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DateGetTime:
|
||||
return ConstantIndex::DATE_GET_TIME_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DateNow:
|
||||
return ConstantIndex::DATE_NOW_INDEX;
|
||||
case BuiltinsStubCSigns::ID::TypedArrayEntries:
|
||||
return ConstantIndex::TYPED_ARRAY_ENTRIES_INDEX;
|
||||
case BuiltinsStubCSigns::ID::TypedArrayKeys:
|
||||
return ConstantIndex::TYPED_ARRAY_KEYS_INDEX;
|
||||
case BuiltinsStubCSigns::ID::TypedArrayValues:
|
||||
return ConstantIndex::TYPED_ARRAY_VALUES_INDEX;
|
||||
case BuiltinsStubCSigns::ID::GlobalIsFinite:
|
||||
return ConstantIndex::GLOBAL_IS_FINITE_INDEX;
|
||||
case BuiltinsStubCSigns::ID::GlobalIsNan:
|
||||
@ -509,6 +532,10 @@ public:
|
||||
return ConstantIndex::DATA_VIEW_SET_UINT16_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint32:
|
||||
return ConstantIndex::DATA_VIEW_SET_UINT32_INDEX;
|
||||
case BuiltinsStubCSigns::ID::BigIntAsIntN:
|
||||
return ConstantIndex::BIGINT_AS_INTN_INDEX;
|
||||
case BuiltinsStubCSigns::ID::BigIntAsUintN:
|
||||
return ConstantIndex::BIGINT_AS_UINTN_INDEX;
|
||||
case BuiltinsStubCSigns::ID::NumberIsFinite:
|
||||
return ConstantIndex::NUMBER_IS_FINITE_INDEX;
|
||||
case BuiltinsStubCSigns::ID::NumberIsInteger:
|
||||
@ -562,11 +589,19 @@ public:
|
||||
{MathMax, "Math.max"},
|
||||
{MathMin, "Math.min"},
|
||||
{DateGetTime, "Date.prototype.getTime"},
|
||||
{DateNow, "Date.now"},
|
||||
{TypedArrayEntries, "TypedArray.entries"},
|
||||
{TypedArrayKeys, "TypedArray.keys"},
|
||||
{TypedArrayValues, "TypedArray.values"},
|
||||
{GlobalIsFinite, "isFinite"},
|
||||
{GlobalIsNan, "isNan"},
|
||||
{BigIntAsIntN, "BigInt.asIntN"},
|
||||
{BigIntAsUintN, "BigInt.asUintN"},
|
||||
{MapGet, "Map.get"},
|
||||
{MapHas, "Map.has"},
|
||||
{SetHas, "Set.has"},
|
||||
{MapDelete, "Map.delete"},
|
||||
{SetDelete, "Set.delete"},
|
||||
};
|
||||
if (builtinId2Str.count(id) > 0) {
|
||||
return builtinId2Str.at(id);
|
||||
@ -615,8 +650,13 @@ public:
|
||||
{"sort", ArraySort},
|
||||
{"stringify", JsonStringify},
|
||||
{"getTime", DateGetTime},
|
||||
{"now", DateNow},
|
||||
{"isFinite", GlobalIsFinite},
|
||||
{"isNan", GlobalIsNan},
|
||||
{"asIntN", BigIntAsIntN},
|
||||
{"asUintN", BigIntAsUintN},
|
||||
{"mapDelete", MapDelete},
|
||||
{"setDelete", SetDelete},
|
||||
};
|
||||
if (str2BuiltinId.count(idStr) > 0) {
|
||||
return str2BuiltinId.at(idStr);
|
||||
|
@ -219,7 +219,7 @@ void BuiltinsCollectionStubBuilder<CollectionType>::Delete(Variable *result, Lab
|
||||
LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_);
|
||||
res = linkedHashTableStubBuilder.Delete(linkedTable, key);
|
||||
}
|
||||
*result = res;
|
||||
*result = BooleanToTaggedBooleanPtr(res);
|
||||
Jump(exit);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "ecmascript/byte_array.h"
|
||||
#include "ecmascript/compiler/builtins/builtins_array_stub_builder.h"
|
||||
#include "ecmascript/compiler/new_object_stub_builder.h"
|
||||
#include "ecmascript/js_iterator.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
GateRef BuiltinsTypedArrayStubBuilder::GetDataPointFromBuffer(GateRef arrBuf)
|
||||
@ -2289,4 +2290,44 @@ void BuiltinsTypedArrayStubBuilder::FindIndex(GateRef glue, GateRef thisValue, G
|
||||
Bind(&loopExit);
|
||||
Jump(exit);
|
||||
}
|
||||
|
||||
void BuiltinsTypedArrayStubBuilder::Entries(GateRef glue, GateRef thisValue, GateRef numArgs,
|
||||
Variable *result, Label *exit, Label *slowPath)
|
||||
{
|
||||
BuildArrayIterator(glue, thisValue, numArgs, result, exit, slowPath, IterationKind::KEY_AND_VALUE);
|
||||
}
|
||||
|
||||
void BuiltinsTypedArrayStubBuilder::Keys(GateRef glue, GateRef thisValue, GateRef numArgs,
|
||||
Variable *result, Label *exit, Label *slowPath)
|
||||
{
|
||||
BuildArrayIterator(glue, thisValue, numArgs, result, exit, slowPath, IterationKind::KEY);
|
||||
}
|
||||
|
||||
void BuiltinsTypedArrayStubBuilder::Values(GateRef glue, GateRef thisValue, GateRef numArgs,
|
||||
Variable *result, Label *exit, Label *slowPath)
|
||||
{
|
||||
BuildArrayIterator(glue, thisValue, numArgs, result, exit, slowPath, IterationKind::VALUE);
|
||||
}
|
||||
|
||||
void BuiltinsTypedArrayStubBuilder::BuildArrayIterator(GateRef glue, GateRef thisValue,
|
||||
[[maybe_unused]] GateRef numArgs, Variable *result, Label *exit, Label *slowPath, IterationKind iteratorKind)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
||||
Label thisExists(env);
|
||||
Label isEcmaObject(env);
|
||||
Label isTypedArray(env);
|
||||
|
||||
BRANCH(BoolOr(TaggedIsHole(thisValue), TaggedIsUndefinedOrNull(thisValue)), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
BRANCH(IsEcmaObject(thisValue), &isEcmaObject, slowPath);
|
||||
Bind(&isEcmaObject);
|
||||
BRANCH(IsTypedArray(thisValue), &isTypedArray, slowPath);
|
||||
Bind(&isTypedArray);
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetGlue(glue);
|
||||
GateRef kind = Int32(static_cast<int32_t>(iteratorKind));
|
||||
newBuilder.CreateJSTypedArrayIterator(result, exit, thisValue, kind);
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -78,6 +78,9 @@ private:
|
||||
{
|
||||
return GetEnvironment()->GetBuilder()->ChangeTaggedPointerToInt64(x);
|
||||
}
|
||||
private:
|
||||
void BuildArrayIterator(GateRef glue, GateRef thisValue, GateRef numArgs,
|
||||
Variable *result, Label *exit, Label *slowPath, IterationKind iteratorKind);
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_BUILTINS_TYPEDARRAY_STUB_BUILDER_H
|
@ -548,7 +548,7 @@ GateRef LinkedHashTableStubBuilder<LinkedHashTableType, LinkedHashTableObject>::
|
||||
Label cfgEntry(env);
|
||||
env->SubCfgEntry(&cfgEntry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(res, VariableType::JS_ANY(), TaggedFalse());
|
||||
DEFVARIABLE(res, VariableType::BOOL(), False());
|
||||
HashStubBuilder hashBuilder(this, glue_);
|
||||
GateRef hash = hashBuilder.GetHash(key);
|
||||
GateRef entry = FindElement(linkedTable, key, hash);
|
||||
@ -557,7 +557,7 @@ GateRef LinkedHashTableStubBuilder<LinkedHashTableType, LinkedHashTableObject>::
|
||||
Bind(&findEntry);
|
||||
{
|
||||
RemoveEntry(linkedTable, entry);
|
||||
res = TaggedTrue();
|
||||
res = True();
|
||||
Jump(&exit);
|
||||
}
|
||||
|
||||
|
@ -286,6 +286,9 @@ GateRef BuiltinLowering::CheckPara(GateRef gate, GateRef funcCheck)
|
||||
case BuiltinsStubCSigns::ID::ArrayIteratorProtoNext:
|
||||
case BuiltinsStubCSigns::ID::IteratorProtoReturn:
|
||||
case BuiltinsStubCSigns::ID::NumberConstructor:
|
||||
case BuiltinsStubCSigns::ID::TypedArrayEntries:
|
||||
case BuiltinsStubCSigns::ID::TypedArrayKeys:
|
||||
case BuiltinsStubCSigns::ID::TypedArrayValues:
|
||||
// Don't need check para
|
||||
return funcCheck;
|
||||
default: {
|
||||
|
@ -1326,6 +1326,36 @@ DEF_CALL_SIGNATURE(NumberHelperStringToDouble)
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CallBigIntAsIntN)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature signature("CallBigIntAsIntN", 0, 2, ArgumentsOrder::DEFAULT_ORDER,
|
||||
VariableType::JS_POINTER());
|
||||
*callSign = signature;
|
||||
std::array<VariableType, 2> params = { // 2 : 2 input parameters
|
||||
VariableType::FLOAT64(),
|
||||
VariableType::JS_POINTER()
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetGCLeafFunction(true);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CallBigIntAsUintN)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature signature("CallBigIntAsUintN", 0, 2, ArgumentsOrder::DEFAULT_ORDER,
|
||||
VariableType::JS_POINTER());
|
||||
*callSign = signature;
|
||||
std::array<VariableType, 2> params = { // 2 : 2 input parameters
|
||||
VariableType::FLOAT64(),
|
||||
VariableType::JS_POINTER(),
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetGCLeafFunction(true);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(GetStringToListCacheArray)
|
||||
{
|
||||
// 1 : 1 input parameters
|
||||
@ -1960,6 +1990,15 @@ DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME(FloatPow)
|
||||
|
||||
#undef DEF_FLOAT_BINARY_CALL_SIGNATURE_BY_NAME
|
||||
|
||||
DEF_CALL_SIGNATURE(CallDateNow)
|
||||
{
|
||||
CallSignature signature("CallDateNow", 0, 0, ArgumentsOrder::DEFAULT_ORDER,
|
||||
VariableType::FLOAT64());
|
||||
*callSign = signature;
|
||||
callSign->SetGCLeafFunction(true);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(FindElementWithCache)
|
||||
{
|
||||
// 4 : 4 input parameters
|
||||
@ -2411,6 +2450,26 @@ DEF_CALL_SIGNATURE(JSSetHas)
|
||||
});
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(JSMapDelete)
|
||||
{
|
||||
*callSign = CallSignature("JSMapDelete", 0, ArgumentsOrder::DEFAULT_ORDER, VariableType::BOOL(),
|
||||
{
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // obj
|
||||
VariableType::JS_ANY(), // key
|
||||
});
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(JSSetDelete)
|
||||
{
|
||||
*callSign = CallSignature("JSSetDelete", 0, ArgumentsOrder::DEFAULT_ORDER, VariableType::BOOL(),
|
||||
{
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // obj
|
||||
VariableType::JS_ANY(), // key
|
||||
});
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(FastStringEqual)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
@ -2478,4 +2537,48 @@ DEF_CALL_SIGNATURE(CopyTypedArrayBuffer)
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CreateJSTypedArrayEntries)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature signature("CreateJSTypedArrayEntries", 0, 2,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = signature;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // obj
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CreateJSTypedArrayKeys)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature signature("CreateJSTypedArrayKeys", 0, 2,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = signature;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // obj
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CreateJSTypedArrayValues)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature signature("CreateJSTypedArrayValues", 0, 2,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = signature;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // obj
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -432,6 +432,8 @@ private:
|
||||
V(StringsAreEquals) \
|
||||
V(BigIntEquals) \
|
||||
V(BigIntSameValueZero) \
|
||||
V(CallBigIntAsIntN) \
|
||||
V(CallBigIntAsUintN) \
|
||||
V(Dump) \
|
||||
V(DebugDump) \
|
||||
V(DumpWithHint) \
|
||||
@ -474,6 +476,7 @@ private:
|
||||
V(FloatFloor) \
|
||||
V(FloatPow) \
|
||||
V(FloatCeil) \
|
||||
V(CallDateNow) \
|
||||
V(NumberIsFinite) \
|
||||
V(FindElementWithCache) \
|
||||
V(MarkingBarrier) \
|
||||
@ -514,6 +517,11 @@ private:
|
||||
V(JSMapGet) \
|
||||
V(JSMapHas) \
|
||||
V(JSSetHas) \
|
||||
V(JSMapDelete) \
|
||||
V(JSSetDelete) \
|
||||
V(CreateJSTypedArrayEntries) \
|
||||
V(CreateJSTypedArrayKeys) \
|
||||
V(CreateJSTypedArrayValues) \
|
||||
V(JSHClassFindProtoTransitions) \
|
||||
V(NumberHelperStringToDouble) \
|
||||
V(GetStringToListCacheArray) \
|
||||
|
@ -210,6 +210,14 @@ GateRef CircuitBuilder::GetLengthOfJSTypedArray(GateRef array)
|
||||
return Load(VariableType::INT32(), array, IntPtr(JSTypedArray::ARRAY_LENGTH_OFFSET));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsTypedArray(GateRef array)
|
||||
{
|
||||
GateRef hclass = LoadHClass(array);
|
||||
GateRef type = GetObjectType(hclass);
|
||||
return BoolAnd(Int32GreaterThan(type, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
|
||||
Int32GreaterThanOrEqual(Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_LAST)), type));
|
||||
}
|
||||
|
||||
void CircuitBuilder::Jump(Label *label)
|
||||
{
|
||||
ASSERT(label);
|
||||
|
@ -202,6 +202,7 @@ public:
|
||||
GateRef GetElementsArray(GateRef object);
|
||||
GateRef GetLengthOfTaggedArray(GateRef array);
|
||||
GateRef GetLengthOfJSTypedArray(GateRef array);
|
||||
GateRef IsTypedArray(GateRef array);
|
||||
GateRef GetSuperConstructor(GateRef ctor);
|
||||
GateRef Merge(const std::vector<GateRef> &inList);
|
||||
GateRef Selector(OpCode opcode, MachineType machineType, GateRef control, const std::vector<GateRef> &values,
|
||||
@ -495,6 +496,7 @@ public:
|
||||
GateRef ElementsKindCheck(GateRef receiver, ElementsKind kind, ArrayMetaDataAccessor::Mode mode);
|
||||
GateRef COWArrayCheck(GateRef gate);
|
||||
GateRef EcmaStringCheck(GateRef gate);
|
||||
GateRef EcmaMapCheck(GateRef gate);
|
||||
GateRef FlattenTreeStringCheck(GateRef gate);
|
||||
GateRef HClassStableArrayCheck(GateRef gate, GateRef frameState, ArrayMetaDataAccessor accessor);
|
||||
GateRef ArrayGuardianCheck(GateRef frameState);
|
||||
@ -614,6 +616,7 @@ public:
|
||||
GateRef LoadArrayLength(GateRef array);
|
||||
inline GateRef LoadFromTaggedArray(GateRef array, size_t index);
|
||||
GateRef LoadStringLength(GateRef string);
|
||||
GateRef LoadMapSize(GateRef string);
|
||||
GateRef LoadConstOffset(VariableType type, GateRef receiver, size_t offset,
|
||||
MemoryOrder order = MemoryOrder::Default());
|
||||
GateRef LoadHClassFromUnsharedConstpool(GateRef constpool, size_t index);
|
||||
@ -646,6 +649,7 @@ public:
|
||||
GateRef TypedCreateObjWithBuffer(std::vector<GateRef> &valueIn);
|
||||
template<TypedLoadOp Op>
|
||||
GateRef ConvertJSArrayHoleAsUndefined(GateRef receiver);
|
||||
GateRef BuildBigIntAsIntN(const GateMetaData* op, std::vector<GateRef> &&args);
|
||||
|
||||
// bit operation
|
||||
inline GateRef TaggedIsInt(GateRef x);
|
||||
@ -697,6 +701,7 @@ public:
|
||||
inline GateRef TaggedObjectBothAreString(GateRef x, GateRef y);
|
||||
inline GateRef TaggedObjectIsEcmaObject(GateRef obj);
|
||||
inline GateRef TaggedObjectIsByteArray(GateRef obj);
|
||||
inline GateRef TaggedObjectIsMap(GateRef obj);
|
||||
inline GateRef TaggedObjectIsDataView(GateRef obj);
|
||||
inline GateRef IsSpecialHole(GateRef x);
|
||||
inline GateRef IsNotSpecialHole(GateRef x);
|
||||
@ -836,6 +841,8 @@ public:
|
||||
template<OpCode Op, MachineType Type>
|
||||
inline GateRef BinaryOpWithOverflow(GateRef x, GateRef y);
|
||||
|
||||
GateRef BuildTypedArrayIterator(GateRef gate, const GateMetaData* op);
|
||||
|
||||
#define ARITHMETIC_BINARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \
|
||||
inline GateRef NAME(GateRef x, GateRef y, GateType type = GateType::Empty(), const char* comment = nullptr) \
|
||||
{ \
|
||||
|
@ -1175,6 +1175,79 @@ void JSSetHasStubBuilder::GenerateCircuit()
|
||||
Return(builder.Has(linkedTable, key));
|
||||
}
|
||||
|
||||
void CreateJSTypedArrayEntriesStubBuilder::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label exit(env);
|
||||
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef obj = TaggedArgument(1);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetGlue(glue);
|
||||
GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY_AND_VALUE));
|
||||
newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind);
|
||||
Bind(&exit);
|
||||
Return(*result);
|
||||
}
|
||||
|
||||
void CreateJSTypedArrayKeysStubBuilder::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label exit(env);
|
||||
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef obj = TaggedArgument(1);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetGlue(glue);
|
||||
GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY));
|
||||
newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind);
|
||||
Bind(&exit);
|
||||
Return(*result);
|
||||
}
|
||||
|
||||
void CreateJSTypedArrayValuesStubBuilder::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label exit(env);
|
||||
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef obj = TaggedArgument(1);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetGlue(glue);
|
||||
GateRef kind = Int32(static_cast<int32_t>(IterationKind::VALUE));
|
||||
newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind);
|
||||
Bind(&exit);
|
||||
Return(*result);
|
||||
}
|
||||
|
||||
void JSMapDeleteStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef obj = TaggedArgument(1);
|
||||
GateRef key = TaggedArgument(2U);
|
||||
|
||||
LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue);
|
||||
GateRef linkedTable = builder.GetLinked(obj);
|
||||
Return(builder.Delete(linkedTable, key));
|
||||
}
|
||||
|
||||
void JSSetDeleteStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef obj = TaggedArgument(1);
|
||||
GateRef key = TaggedArgument(2U);
|
||||
|
||||
LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue);
|
||||
GateRef linkedTable = builder.GetLinked(obj);
|
||||
Return(builder.Delete(linkedTable, key));
|
||||
}
|
||||
|
||||
CallSignature CommonStubCSigns::callSigns_[CommonStubCSigns::NUM_OF_STUBS];
|
||||
|
||||
void CommonStubCSigns::Initialize()
|
||||
|
@ -94,6 +94,11 @@ namespace panda::ecmascript::kungfu {
|
||||
V(JSMapGet) \
|
||||
V(JSMapHas) \
|
||||
V(JSSetHas) \
|
||||
V(JSMapDelete) \
|
||||
V(JSSetDelete) \
|
||||
V(CreateJSTypedArrayEntries) \
|
||||
V(CreateJSTypedArrayKeys) \
|
||||
V(CreateJSTypedArrayValues) \
|
||||
V(GetSingleCharCodeByIndex) \
|
||||
V(FastStringEqual) \
|
||||
V(FastStringAdd) \
|
||||
|
@ -145,6 +145,19 @@ GateRef CircuitBuilder::EcmaStringCheck(GateRef gate)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::EcmaMapCheck(GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->EcmaMapCheck(),
|
||||
MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::FlattenTreeStringCheck(GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
@ -896,6 +909,18 @@ GateRef CircuitBuilder::LoadStringLength(GateRef string)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LoadMapSize(GateRef string)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto ret = GetCircuit()->NewGate(circuit_->LoadMapSize(), MachineType::I64,
|
||||
{ currentControl, currentDepend, string }, GateType::IntType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LoadConstOffset(VariableType type, GateRef receiver, size_t offset, MemoryOrder order)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
@ -1780,6 +1805,32 @@ GateRef CircuitBuilder::NumberIsSafeInteger(GateRef gate)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::BuildBigIntAsIntN(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::TaggedValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::BuildTypedArrayIterator(GateRef gate, const GateMetaData* op)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef ret =
|
||||
GetCircuit()->NewGate(op, MachineType::I64,
|
||||
{ currentControl, currentDepend, gate }, GateType::AnyType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsASCIICharacter(GateRef gate)
|
||||
{
|
||||
return Int32UnsignedLessThan(Int32Sub(gate, Int32(1)), Int32(base::utf_helper::UTF8_1B_MAX));
|
||||
|
@ -94,6 +94,12 @@ GateRef CircuitBuilder::TaggedObjectIsByteArray(GateRef obj)
|
||||
return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::BYTE_ARRAY)));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::TaggedObjectIsMap(GateRef obj)
|
||||
{
|
||||
GateRef objectType = GetObjectType(LoadHClass(obj));
|
||||
return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_MAP)));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::TaggedObjectIsDataView(GateRef obj)
|
||||
{
|
||||
GateRef objectType = GetObjectType(LoadHClass(obj));
|
||||
|
@ -41,6 +41,7 @@ namespace panda::ecmascript::kungfu {
|
||||
V(COWArrayCheck, COW_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(ConvertHoleAsUndefined, CONVERT_HOLE_AS_UNDEFINED, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(EcmaStringCheck, ECMA_STRING_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(EcmaMapCheck, ECMA_MAP_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(FinishAllocate, FINISH_ALLOCATE, GateFlags::NONE_FLAG, 0, 1, 1) \
|
||||
V(FlattenTreeStringCheck, FLATTEN_TREE_STRING_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(HeapObjectCheck, HEAP_OBJECT_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
@ -51,6 +52,7 @@ namespace panda::ecmascript::kungfu {
|
||||
V(LoadSetter, LOAD_SETTER, GateFlags::NO_WRITE, 0, 1, 2) \
|
||||
V(LoadArrayLength, LOAD_ARRAY_LENGTH, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(LoadStringLength, LOAD_STRING_LENGTH, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(LoadMapSize, LOAD_MAP_SIZE, 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(TypedNewAllocateThis, TYPED_NEW_ALLOCATE_THIS, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
@ -60,6 +62,9 @@ namespace panda::ecmascript::kungfu {
|
||||
V(IndexCheck, INDEX_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(MonoLoadPropertyOnProto, MONO_LOAD_PROPERTY_ON_PROTO, GateFlags::CHECKABLE, 1, 1, 4) \
|
||||
V(StringFromSingleCharCode, STRING_FROM_SINGLE_CHAR_CODE, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(TypedArrayEntries, TYPED_ARRAY_ENTRIES, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(TypedArrayKeys, TYPED_ARRAY_KEYS, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(TypedArrayValues, TYPED_ARRAY_VALUES, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(MigrateFromRawValueToHeapValues, MIGRATE_FROM_RAWVALUE_TO_HEAPVALUES, GateFlags::NONE_FLAG, 1, 1, 3) \
|
||||
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) \
|
||||
@ -117,10 +122,15 @@ namespace panda::ecmascript::kungfu {
|
||||
V(ArrayBufferIsView, ARRAY_BUFFER_IS_VIEW, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(DataViewGet, DATA_VIEW_GET, GateFlags::NO_WRITE, 1, 1, 5) \
|
||||
V(DataViewSet, DATA_VIEW_SET, GateFlags::NO_WRITE, 1, 1, 6) \
|
||||
V(BigIntAsIntN, BIGINT_ASINTN, GateFlags::NO_WRITE, 1, 1, 3) \
|
||||
V(BigIntAsUintN, BIGINT_ASUINTN, GateFlags::NO_WRITE, 1, 1, 3) \
|
||||
V(MapGet, MAP_GET, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(DateGetTime, DATE_GET_TIME, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(MapHas, MAP_HAS, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(SetHas, SET_HAS, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(MapDelete, MAP_DELETE, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(SetDelete, SET_DELETE, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(DateNow, DATE_NOW, GateFlags::NONE_FLAG, 1, 1, 0) \
|
||||
MCR_BINARY_GATE_META_DATA_CACHE_LIST(V)
|
||||
|
||||
#define MCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(V) \
|
||||
|
@ -20,6 +20,10 @@
|
||||
#include "ecmascript/compiler/circuit_builder_helper.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/new_object_stub_builder.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/js_iterator.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
|
||||
@ -90,6 +94,15 @@ void NativeInlineLowering::RunNativeInlineLowering()
|
||||
case BuiltinsStubCSigns::ID::NumberIsSafeInteger:
|
||||
TryInlineNumberIsSafeInteger(gate, argc, skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::TypedArrayEntries:
|
||||
TryInlineTypedArrayIteratorBuiltin(gate, id, circuit_->TypedArrayEntries(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::TypedArrayKeys:
|
||||
TryInlineTypedArrayIteratorBuiltin(gate, id, circuit_->TypedArrayKeys(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::TypedArrayValues:
|
||||
TryInlineTypedArrayIteratorBuiltin(gate, id, circuit_->TypedArrayValues(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::MathAcos:
|
||||
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAcos(), skipThis);
|
||||
break;
|
||||
@ -221,6 +234,10 @@ void NativeInlineLowering::RunNativeInlineLowering()
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint32:
|
||||
TryInlineDataViewSet(gate, argc, id);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::BigIntAsIntN:
|
||||
case BuiltinsStubCSigns::ID::BigIntAsUintN:
|
||||
TryInlineBigIntAsIntN(gate, argc, id, skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::MapGet:
|
||||
InlineStubBuiltin(gate, 1U, argc, id, circuit_->MapGet(), skipThis);
|
||||
break;
|
||||
@ -230,6 +247,15 @@ void NativeInlineLowering::RunNativeInlineLowering()
|
||||
case BuiltinsStubCSigns::ID::SetHas:
|
||||
InlineStubBuiltin(gate, 1U, argc, id, circuit_->SetHas(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::DateNow:
|
||||
TryInlineWhitoutParamBuiltin(gate, argc, id, circuit_->DateNow(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::MapDelete:
|
||||
InlineStubBuiltin(gate, 1U, argc, id, circuit_->MapDelete(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::SetDelete:
|
||||
InlineStubBuiltin(gate, 1U, argc, id, circuit_->SetDelete(), skipThis);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -354,6 +380,53 @@ void NativeInlineLowering::TryInlineNumberIsSafeInteger(GateRef gate, size_t arg
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineBigIntAsIntN(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
|
||||
bool skipThis)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
bool firstParam = skipThis ? 1 : 0;
|
||||
if (argc < 2U) {
|
||||
return;
|
||||
}
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
|
||||
builder_.IntPtr(static_cast<int64_t>(id)));
|
||||
}
|
||||
if (EnableTrace()) {
|
||||
AddTraceLogs(gate, id);
|
||||
}
|
||||
GateRef bits = acc_.GetValueIn(gate, firstParam);
|
||||
GateRef bigint = acc_.GetValueIn(gate, firstParam + 1);
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
bool isUnsigned = (id == BuiltinsStubCSigns::ID::BigIntAsUintN);
|
||||
const auto* op = isUnsigned ? circuit_->BigIntAsUintN() : circuit_->BigIntAsIntN();
|
||||
GateRef ret = builder_.BuildBigIntAsIntN(op, {bits, bigint, frameState});
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineTypedArrayIteratorBuiltin(GateRef gate,
|
||||
BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis)
|
||||
{
|
||||
if (!skipThis) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallThis0TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(), builder_.IntPtr(static_cast<int64_t>(id)), {tacc.GetThisObj()});
|
||||
}
|
||||
|
||||
if (EnableTrace()) {
|
||||
AddTraceLogs(gate, id);
|
||||
}
|
||||
|
||||
GateRef ret = builder_.BuildTypedArrayIterator(acc_.GetValueIn(gate, 0), op);
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineMathUnaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis)
|
||||
{
|
||||
@ -376,6 +449,24 @@ void NativeInlineLowering::TryInlineMathUnaryBuiltin(GateRef gate, size_t argc,
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineWhitoutParamBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
bool firstParam = skipThis ? 1 : 0;
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
|
||||
builder_.IntPtr(static_cast<int64_t>(id)));
|
||||
}
|
||||
|
||||
if (EnableTrace()) {
|
||||
AddTraceLogs(gate, id);
|
||||
}
|
||||
|
||||
GateRef ret = builder_.BuildControlDependOp(op, {});
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineMathClz32Builtin(GateRef gate, size_t argc, bool skipThis)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
@ -29,9 +29,10 @@
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class NativeInlineLowering {
|
||||
public:
|
||||
explicit NativeInlineLowering(Circuit *circuit, PassContext *ctx, bool enableLog, const std::string& name)
|
||||
explicit NativeInlineLowering(Circuit *circuit, CompilationConfig* cmpCfg, PassContext *ctx, bool enableLog,
|
||||
const std::string& name)
|
||||
: circuit_(circuit),
|
||||
builder_(circuit),
|
||||
builder_(circuit, cmpCfg),
|
||||
acc_(circuit),
|
||||
glue_(acc_.GetGlueFromArgList()),
|
||||
tsManager_(ctx->GetTSManager()),
|
||||
@ -50,6 +51,8 @@ private:
|
||||
void TryInlineNumberIsInteger(GateRef gate, size_t argc, bool skipThis);
|
||||
void TryInlineNumberIsNaN(GateRef gate, size_t argc, bool skipThis);
|
||||
void TryInlineNumberIsSafeInteger(GateRef gate, size_t argc, bool skipThis);
|
||||
void TryInlineTypedArrayIteratorBuiltin(GateRef gate, BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis);
|
||||
void TryInlineMathUnaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, const GateMetaData* op,
|
||||
bool skipThis);
|
||||
void TryInlineMathBinaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, const GateMetaData* op,
|
||||
@ -64,11 +67,14 @@ private:
|
||||
double defaultValue, bool skipThis);
|
||||
void TryInlineMathClz32Builtin(GateRef gate, size_t argc, bool skipThis);
|
||||
void TryInlineArrayBufferIsView(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis);
|
||||
void TryInlineBigIntAsIntN(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis);
|
||||
void TryInlineDataViewGet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id);
|
||||
void TryInlineDataViewSet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id);
|
||||
void InlineStubBuiltin(GateRef gate, size_t builtinArgc, size_t realArgc, BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis);
|
||||
void TryInlineDateGetTime(GateRef gate, size_t argc, bool skipThis);
|
||||
void TryInlineWhitoutParamBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis);
|
||||
|
||||
void AddTraceLogs(GateRef gate, BuiltinsStubCSigns::ID id);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/lexical_env.h"
|
||||
#include "ecmascript/mem/mem.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_map_iterator.h"
|
||||
#include "ecmascript/js_set_iterator.h"
|
||||
#include "ecmascript/js_set.h"
|
||||
@ -1555,6 +1556,61 @@ template void NewObjectStubBuilder::CreateJSCollectionIterator<JSSetIterator, JS
|
||||
template void NewObjectStubBuilder::CreateJSCollectionIterator<JSMapIterator, JSMap>(
|
||||
Variable *result, Label *exit, GateRef set, GateRef kind);
|
||||
|
||||
void NewObjectStubBuilder::CreateJSTypedArrayIterator(Variable *result, Label *exit, GateRef thisValue, GateRef kind)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
size_ = IntPtr(JSArrayIterator::SIZE);
|
||||
|
||||
ConstantIndex iterClassIdx = ConstantIndex::JS_ARRAY_ITERATOR_CLASS_INDEX;
|
||||
GateRef iteratorHClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue_, iterClassIdx);
|
||||
|
||||
Label thisExists(env);
|
||||
Label isEcmaObject(env);
|
||||
Label isTypedArray(env);
|
||||
Label throwTypeError(env);
|
||||
|
||||
BRANCH(BoolOr(TaggedIsHole(thisValue), TaggedIsUndefinedOrNull(thisValue)), &throwTypeError, &thisExists);
|
||||
Bind(&thisExists);
|
||||
BRANCH(IsEcmaObject(thisValue), &isEcmaObject, &throwTypeError);
|
||||
Bind(&isEcmaObject);
|
||||
BRANCH(IsTypedArray(thisValue), &isTypedArray, &throwTypeError);
|
||||
Bind(&isTypedArray);
|
||||
|
||||
Label noException(env);
|
||||
// Be careful. NO GC is allowed when initization is not complete.
|
||||
AllocateInYoung(result, exit, &noException, iteratorHClass);
|
||||
Bind(&noException);
|
||||
{
|
||||
StoreBuiltinHClass(glue_, result->ReadVariable(), iteratorHClass);
|
||||
SetHash(glue_, result->ReadVariable(), Int64(JSTaggedValue(0).GetRawData()));
|
||||
auto emptyArray = GetGlobalConstantValue(
|
||||
VariableType::JS_POINTER(), glue_, ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX);
|
||||
SetPropertiesArray(VariableType::INT64(), glue_, result->ReadVariable(), emptyArray);
|
||||
SetElementsArray(VariableType::INT64(), glue_, result->ReadVariable(), emptyArray);
|
||||
|
||||
GateRef iteratorOffset = IntPtr(JSArrayIterator::ITERATED_ARRAY_OFFSET);
|
||||
Store(VariableType::JS_POINTER(), glue_, result->ReadVariable(), iteratorOffset, thisValue,
|
||||
MemoryOrder::NeedBarrier());
|
||||
|
||||
// SetIteratorNextIndex
|
||||
GateRef nextIndexOffset = IntPtr(JSArrayIterator::NEXT_INDEX_OFFSET);
|
||||
Store(VariableType::INT32(), glue_, result->ReadVariable(), nextIndexOffset, Int32(0));
|
||||
|
||||
// SetIterationKind
|
||||
GateRef kindBitfieldOffset = IntPtr(JSArrayIterator::BIT_FIELD_OFFSET);
|
||||
Store(VariableType::INT32(), glue_, result->ReadVariable(), kindBitfieldOffset, kind);
|
||||
Jump(exit);
|
||||
}
|
||||
|
||||
Bind(&throwTypeError);
|
||||
{
|
||||
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(LenGreaterThanMax));
|
||||
CallRuntime(glue_, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(taggedId) });
|
||||
result->WriteVariable(Exception());
|
||||
Jump(exit);
|
||||
}
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::NewTaggedSubArray(GateRef glue, GateRef srcTypedArray,
|
||||
GateRef elementSize, GateRef newLength, GateRef beginIndex, GateRef arrayCls, GateRef buffer)
|
||||
{
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
void NewMutantTaggedArrayChecked(Variable *result, GateRef len, Label *exit);
|
||||
template <typename IteratorType, typename CollectionType>
|
||||
void CreateJSCollectionIterator(Variable *result, Label *exit, GateRef set, GateRef kind);
|
||||
void CreateJSTypedArrayIterator(Variable *result, Label *exit, GateRef set, GateRef kind);
|
||||
GateRef NewTaggedSubArray(GateRef glue, GateRef srcTypedArray, GateRef elementSize, GateRef newLength,
|
||||
GateRef beginIndex, GateRef arrayCls, GateRef buffer);
|
||||
GateRef NewTypedArray(GateRef glue, GateRef srcTypedArray, GateRef srcType, GateRef length);
|
||||
|
@ -94,6 +94,10 @@ void NumberSpeculativeLowering::VisitGate(GateRef gate)
|
||||
VisitLoadStringLength(gate);
|
||||
break;
|
||||
}
|
||||
case OpCode::LOAD_MAP_SIZE: {
|
||||
VisitLoadMapSize(gate);
|
||||
break;
|
||||
}
|
||||
case OpCode::LOAD_PROPERTY: {
|
||||
VisitLoadProperty(gate);
|
||||
break;
|
||||
@ -572,6 +576,12 @@ void NumberSpeculativeLowering::VisitLoadStringLength(GateRef gate)
|
||||
acc_.SetMachineType(gate, MachineType::I32);
|
||||
}
|
||||
|
||||
void NumberSpeculativeLowering::VisitLoadMapSize(GateRef gate)
|
||||
{
|
||||
acc_.SetGateType(gate, GateType::NJSValue());
|
||||
acc_.SetMachineType(gate, MachineType::I32);
|
||||
}
|
||||
|
||||
void NumberSpeculativeLowering::VisitLoadElement(GateRef gate)
|
||||
{
|
||||
auto op = acc_.GetTypedLoadOp(gate);
|
||||
|
@ -51,6 +51,7 @@ private:
|
||||
void VisitIndexCheck(GateRef gate);
|
||||
void VisitLoadArrayLength(GateRef gate);
|
||||
void VisitLoadStringLength(GateRef gate);
|
||||
void VisitLoadMapSize(GateRef gate);
|
||||
void VisitLoadElement(GateRef gate);
|
||||
void VisitLoadProperty(GateRef gate);
|
||||
void VisitLoadPropertyOnProto(GateRef gate);
|
||||
|
@ -153,6 +153,8 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
return VisitLoadArrayLength(gate);
|
||||
case OpCode::LOAD_STRING_LENGTH:
|
||||
return VisitLoadStringLength(gate);
|
||||
case OpCode::LOAD_MAP_SIZE:
|
||||
return VisitLoadMapSize(gate);
|
||||
case OpCode::LOAD_ELEMENT:
|
||||
return VisitLoadElement(gate);
|
||||
case OpCode::STORE_ELEMENT:
|
||||
@ -241,9 +243,16 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
return VisitDataViewSet(gate);
|
||||
case OpCode::DATE_GET_TIME:
|
||||
return VisitDateGetTime(gate);
|
||||
case OpCode::BIGINT_ASINTN:
|
||||
case OpCode::BIGINT_ASUINTN:
|
||||
return VisitBigIntAsIntN(gate);
|
||||
case OpCode::MAP_HAS:
|
||||
case OpCode::SET_HAS:
|
||||
case OpCode::MAP_DELETE:
|
||||
case OpCode::SET_DELETE:
|
||||
return VisitOthers(gate, GateType::BooleanType());
|
||||
case OpCode::DATE_NOW:
|
||||
return VisitDateNow(gate);
|
||||
case OpCode::JS_BYTECODE:
|
||||
case OpCode::RUNTIME_CALL:
|
||||
case OpCode::PRIMITIVE_TYPE_CHECK:
|
||||
@ -278,6 +287,9 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
case OpCode::TYPED_CALL_BUILTIN_SIDE_EFFECT:
|
||||
case OpCode::MAP_GET:
|
||||
case OpCode::NEW_NUMBER:
|
||||
case OpCode::TYPED_ARRAY_ENTRIES:
|
||||
case OpCode::TYPED_ARRAY_KEYS:
|
||||
case OpCode::TYPED_ARRAY_VALUES:
|
||||
return VisitOthers(gate);
|
||||
default:
|
||||
return Circuit::NullGate();
|
||||
@ -1335,6 +1347,15 @@ GateRef NumberSpeculativeRetype::VisitLoadStringLength(GateRef gate)
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitLoadMapSize(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
return SetOutputType(gate, GateType::IntType());
|
||||
}
|
||||
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitLoadElement(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
@ -1544,6 +1565,7 @@ GateRef NumberSpeculativeRetype::VisitNumberOrGlobalBuiltin(GateRef gate)
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
GateRef input = acc_.GetValueIn(gate, 0);
|
||||
|
||||
// We change IsNan/IsFinite to constant if input is INT32 without check
|
||||
// So we skip tagged input with int profiled type
|
||||
auto type = GetNumberInputTypeInfo(input, true);
|
||||
@ -1720,6 +1742,22 @@ GateRef NumberSpeculativeRetype::VisitMathTrunc(GateRef gate)
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitBigIntAsIntN(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
return SetOutputType(gate, GateType::AnyType());
|
||||
}
|
||||
ASSERT(IsConvert());
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3U);
|
||||
GateRef bits = acc_.GetValueIn(gate, 0);
|
||||
acc_.ReplaceValueIn(gate, ConvertToTagged(CheckAndConvertToFloat64(bits, GateType::NumberType(),
|
||||
ConvertToNumber::BOOL_ONLY)), 0);
|
||||
acc_.ReplaceStateIn(gate, builder_.GetState());
|
||||
acc_.ReplaceDependIn(gate, builder_.GetDepend());
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
TypeInfo NumberSpeculativeRetype::GetNumberInputTypeInfo(GateRef gate, bool skipTagged)
|
||||
{
|
||||
TypeInfo typeInfo = GetOutputTypeInfo(gate);
|
||||
@ -1845,6 +1883,16 @@ GateRef NumberSpeculativeRetype::VisitDateGetTime(GateRef gate)
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitDateNow(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
return SetOutputType(gate, GateType::DoubleType());
|
||||
}
|
||||
ASSERT(IsConvert());
|
||||
// Nothing to do, because don't have inputs
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitMonoLoadPropertyOnProto(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
|
@ -99,11 +99,13 @@ private:
|
||||
template <bool IS_NAN>
|
||||
GateRef VisitNumberOrGlobalBuiltin(GateRef gate);
|
||||
GateRef VisitNumberIsInteger(GateRef gate);
|
||||
GateRef VisitBigIntAsIntN(GateRef gate);
|
||||
GateRef VisitBooleanJump(GateRef gate);
|
||||
GateRef VisitRangeCheckPredicate(GateRef gate);
|
||||
GateRef VisitIndexCheck(GateRef gate);
|
||||
GateRef VisitLoadArrayLength(GateRef gate);
|
||||
GateRef VisitLoadStringLength(GateRef gate);
|
||||
GateRef VisitLoadMapSize(GateRef gate);
|
||||
GateRef VisitLoadElement(GateRef gate);
|
||||
GateRef VisitStoreElement(GateRef gate);
|
||||
GateRef VisitStoreProperty(GateRef gate);
|
||||
@ -125,6 +127,7 @@ private:
|
||||
GateRef VisitMonoCallGetterOnProto(GateRef gate);
|
||||
GateRef VisitMonoStoreProperty(GateRef gate);
|
||||
GateRef VisitDateGetTime(GateRef gate);
|
||||
GateRef VisitDateNow(GateRef gate);
|
||||
|
||||
void ConvertForNumberBinaryOp(GateRef gate);
|
||||
void ConvertForNumberCompareOp(GateRef gate);
|
||||
|
@ -551,8 +551,8 @@ public:
|
||||
}
|
||||
|
||||
if (passOptions->EnableInlineNative()) {
|
||||
NativeInlineLowering nativeInline(data->GetCircuit(), data->GetPassContext(), enableLog,
|
||||
data->GetMethodName());
|
||||
NativeInlineLowering nativeInline(data->GetCircuit(), data->GetCompilerConfig(), data->GetPassContext(),
|
||||
enableLog, data->GetMethodName());
|
||||
nativeInline.RunNativeInlineLowering();
|
||||
}
|
||||
return true;
|
||||
|
@ -61,6 +61,8 @@ GateRef RangeAnalysis::VisitGate(GateRef gate)
|
||||
return VisitLoadArrayLength(gate);
|
||||
case OpCode::LOAD_STRING_LENGTH:
|
||||
return VisitLoadStringLength(gate);
|
||||
case OpCode::LOAD_MAP_SIZE:
|
||||
return VisitLoadMapSize(gate);
|
||||
case OpCode::LOAD_TYPED_ARRAY_LENGTH:
|
||||
return VisitLoadTypedArrayLength(gate);
|
||||
case OpCode::RANGE_GUARD:
|
||||
@ -183,6 +185,12 @@ GateRef RangeAnalysis::VisitLoadStringLength(GateRef gate)
|
||||
return UpdateRange(gate, RangeInfo(0, INT32_MAX));
|
||||
}
|
||||
|
||||
GateRef RangeAnalysis::VisitLoadMapSize(GateRef gate)
|
||||
{
|
||||
ASSERT(IsInt32Type(gate));
|
||||
return UpdateRange(gate, RangeInfo(0, INT32_MAX));
|
||||
}
|
||||
|
||||
GateRef RangeAnalysis::VisitLoadTypedArrayLength(GateRef gate)
|
||||
{
|
||||
TypedArrayMetaDateAccessor accessor = acc_.GetTypedArrayMetaDateAccessor(gate);
|
||||
|
@ -42,6 +42,7 @@ private:
|
||||
GateRef VisitIndexCheck(GateRef gate);
|
||||
GateRef VisitLoadArrayLength(GateRef gate);
|
||||
GateRef VisitLoadStringLength(GateRef gate);
|
||||
GateRef VisitLoadMapSize(GateRef gate);
|
||||
GateRef VisitLoadTypedArrayLength(GateRef gate);
|
||||
GateRef VisitRangeGuard(GateRef gate);
|
||||
template<TypedBinOp Op>
|
||||
|
@ -115,7 +115,10 @@ enum class TypedCallTargetCheckOp : uint8_t;
|
||||
V(IsUndefinedOrHole, ISUNDEFINEDORHOLE) \
|
||||
V(IsNotUndefinedOrHole, ISNOTUNDEFINEDORHOLE) \
|
||||
V(BuiltinInliningTypeGuard, BUILTIN_INLINING_TYPE_GUARD) \
|
||||
V(RangeError, RANGE_ERROR) \
|
||||
V(NotBigInt, NOT_BIG_INT) \
|
||||
V(OsrLoopExit, OSRLOOPEXIT) \
|
||||
V(IsNotMap, ISNOTMAP) \
|
||||
V(IsNotEcmaObject, ISNOTECMAOBJECT) \
|
||||
V(IsNotDataView, ISNOTDATAVIEW) \
|
||||
V(IsNotTaggedBoolean, ISNOTTAGGEDBOOLEAN) \
|
||||
|
@ -977,6 +977,11 @@ public:
|
||||
return types_.size();
|
||||
}
|
||||
|
||||
bool IsBuiltinsMap() const
|
||||
{
|
||||
return types_[0].IsBuiltinsMap();
|
||||
}
|
||||
|
||||
bool IsBuiltinsString() const
|
||||
{
|
||||
return types_[0].IsBuiltinsString();
|
||||
|
@ -828,6 +828,15 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltin(const LoadBulitin
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
EcmaString *sizeString = EcmaString::Cast(compilationEnv_->GlobalConstants()->GetSizeString().GetTaggedObject());
|
||||
if (propString == sizeString) {
|
||||
if (tacc.IsBuiltinsMap()) {
|
||||
LowerTypedLdMapSize(tacc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// (2) other functions
|
||||
return false;
|
||||
}
|
||||
@ -954,6 +963,18 @@ void TypedBytecodeLowering::LowerTypedLdStringLength(const LoadBulitinObjTypeInf
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result);
|
||||
}
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedLdMapSize(const LoadBulitinObjTypeInfoAccessor &tacc)
|
||||
{
|
||||
GateRef gate = tacc.GetGate();
|
||||
GateRef jsMap = tacc.GetReceiver();
|
||||
AddProfiling(gate);
|
||||
if (!Uncheck()) {
|
||||
builder_.EcmaMapCheck(jsMap);
|
||||
}
|
||||
GateRef result = builder_.LoadMapSize(jsMap);
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result);
|
||||
}
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(const LoadBulitinObjTypeInfoAccessor &tacc,
|
||||
BuiltinTypeId type)
|
||||
{
|
||||
|
@ -129,6 +129,7 @@ private:
|
||||
void LowerTypedLdArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
|
||||
void LowerTypedLdTypedArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
|
||||
void LowerTypedLdStringLength(const LoadBulitinObjTypeInfoAccessor &tacc);
|
||||
void LowerTypedLdMapSize(const LoadBulitinObjTypeInfoAccessor &tacc);
|
||||
bool TryLowerTypedLdObjByNameForBuiltinMethod(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
|
||||
|
||||
void LowerTypedLdObjByIndex(GateRef gate);
|
||||
|
@ -25,9 +25,11 @@
|
||||
#include "ecmascript/elements.h"
|
||||
#include "ecmascript/enum_conversion.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_map.h"
|
||||
#include "ecmascript/js_native_pointer.h"
|
||||
#include "ecmascript/js_object.h"
|
||||
#include "ecmascript/js_primitive_ref.h"
|
||||
#include "ecmascript/linked_hash_table.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
#include "ecmascript/subtyping_operator.h"
|
||||
#include "ecmascript/vtable.h"
|
||||
@ -53,12 +55,18 @@ GateRef TypedHCRLowering::VisitGate(GateRef gate)
|
||||
case OpCode::ECMA_STRING_CHECK:
|
||||
LowerEcmaStringCheck(gate);
|
||||
break;
|
||||
case OpCode::ECMA_MAP_CHECK:
|
||||
LowerEcmaMapCheck(gate);
|
||||
break;
|
||||
case OpCode::FLATTEN_TREE_STRING_CHECK:
|
||||
LowerFlattenTreeStringCheck(gate, glue);
|
||||
break;
|
||||
case OpCode::LOAD_STRING_LENGTH:
|
||||
LowerStringLength(gate);
|
||||
break;
|
||||
case OpCode::LOAD_MAP_SIZE:
|
||||
LowerMapSize(gate);
|
||||
break;
|
||||
case OpCode::LOAD_TYPED_ARRAY_LENGTH:
|
||||
LowerLoadTypedArrayLength(gate);
|
||||
break;
|
||||
@ -413,6 +421,21 @@ void TypedHCRLowering::LowerEcmaStringCheck(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void TypedHCRLowering::LowerEcmaMapCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef frameState = GetFrameState(gate);
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
builder_.HeapObjectCheck(receiver, frameState);
|
||||
|
||||
GateRef hclass = builder_.LoadHClass(receiver);
|
||||
GateRef mapHclass = builder_.GetGlobalConstantValue(ConstantIndex::JS_MAP_HCLASS_INDEX);
|
||||
GateRef isMap = builder_.Equal(hclass, mapHclass, "checkHClass");
|
||||
|
||||
builder_.DeoptCheck(isMap, frameState, DeoptType::ISNOTMAP);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void TypedHCRLowering::LowerFlattenTreeStringCheck(GateRef gate, GateRef glue)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
@ -459,6 +482,18 @@ void TypedHCRLowering::LowerStringLength(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), length);
|
||||
}
|
||||
|
||||
void TypedHCRLowering::LowerMapSize(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
|
||||
GateRef linkedMap = builder_.LoadConstOffset(VariableType::JS_ANY(), receiver, JSMap::LINKED_MAP_OFFSET);
|
||||
GateRef mapSizeTagged = builder_.LoadFromTaggedArray(linkedMap, LinkedHashMap::NUMBER_OF_ELEMENTS_INDEX);
|
||||
GateRef mapSize = builder_.TaggedGetInt(mapSizeTagged);
|
||||
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), mapSize);
|
||||
}
|
||||
|
||||
void TypedHCRLowering::LowerLoadTypedArrayLength(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
@ -142,9 +142,11 @@ private:
|
||||
void LowerStableArrayCheck(GateRef gate);
|
||||
void LowerTypedArrayCheck(GateRef gate);
|
||||
void LowerEcmaStringCheck(GateRef gate);
|
||||
void LowerEcmaMapCheck(GateRef gate);
|
||||
void LowerFlattenTreeStringCheck(GateRef gate, GateRef glue);
|
||||
void LowerLoadTypedArrayLength(GateRef gate);
|
||||
void LowerStringLength(GateRef gate);
|
||||
void LowerMapSize(GateRef gate);
|
||||
void LowerLoadProperty(GateRef gate);
|
||||
void LowerCallGetter(GateRef gate, GateRef glue);
|
||||
void LowerStoreProperty(GateRef gate);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "ecmascript/compiler/variable_type.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_bigint.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_hclass.h"
|
||||
#include "ecmascript/js_native_pointer.h"
|
||||
@ -37,6 +38,10 @@
|
||||
#include "ecmascript/js_primitive_ref.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
#include "macros.h"
|
||||
#include "ecmascript/compiler/new_object_stub_builder.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_iterator.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
|
||||
@ -185,6 +190,12 @@ GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
|
||||
case OpCode::ARRAY_BUFFER_IS_VIEW:
|
||||
LowerArrayBufferIsView(gate);
|
||||
break;
|
||||
case OpCode::BIGINT_ASINTN:
|
||||
LowerBigIntAsIntN<false>(gate);
|
||||
break;
|
||||
case OpCode::BIGINT_ASUINTN:
|
||||
LowerBigIntAsIntN<true>(gate);
|
||||
break;
|
||||
case OpCode::NUMBER_IS_FINITE:
|
||||
LowerNumberIsFinite(gate);
|
||||
break;
|
||||
@ -209,6 +220,27 @@ GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
|
||||
case OpCode::SET_HAS:
|
||||
LowerToCommonStub(gate, CommonStubCSigns::JSSetHas);
|
||||
break;
|
||||
case OpCode::DATE_NOW:
|
||||
LowerGeneralWithoutArgs(gate, RTSTUB_ID(CallDateNow));
|
||||
break;
|
||||
case OpCode::TYPED_ARRAY_ENTRIES:
|
||||
LowerTypedArrayIterator(gate, CommonStubCSigns::CreateJSTypedArrayEntries,
|
||||
IterationKind::KEY_AND_VALUE);
|
||||
break;
|
||||
case OpCode::TYPED_ARRAY_KEYS:
|
||||
LowerTypedArrayIterator(gate, CommonStubCSigns::CreateJSTypedArrayKeys,
|
||||
IterationKind::KEY);
|
||||
break;
|
||||
case OpCode::TYPED_ARRAY_VALUES:
|
||||
LowerTypedArrayIterator(gate, CommonStubCSigns::CreateJSTypedArrayValues,
|
||||
IterationKind::VALUE);
|
||||
break;
|
||||
case OpCode::MAP_DELETE:
|
||||
LowerToCommonStub(gate, CommonStubCSigns::JSMapDelete);
|
||||
break;
|
||||
case OpCode::SET_DELETE:
|
||||
LowerToCommonStub(gate, CommonStubCSigns::JSSetDelete);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -255,6 +287,91 @@ void TypedNativeInlineLowering::LowerMathCeilFloorWithRuntimeCall(GateRef gate)
|
||||
}
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
GateRef TypedNativeInlineLowering::AllocateTypedArrayIterator(GateRef glue, GateRef self,
|
||||
GateRef iteratorHClass,
|
||||
IterationKind iterationKind)
|
||||
{
|
||||
GateRef emptyArray = builder_.GetGlobalConstantValue(ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX);
|
||||
GateRef kind = builder_.Int32(static_cast<int32_t>(iterationKind));
|
||||
|
||||
builder_.StartAllocate();
|
||||
|
||||
GateRef iterator = builder_.HeapAlloc(glue, builder_.IntPtr(JSArrayIterator::SIZE),
|
||||
GateType::TaggedValue(), RegionSpaceFlag::IN_YOUNG_SPACE);
|
||||
|
||||
builder_.StoreConstOffset(VariableType::JS_POINTER(), iterator, TaggedObject::HCLASS_OFFSET,
|
||||
iteratorHClass, MemoryOrder::NeedBarrierAndAtomic());
|
||||
builder_.StoreConstOffset(VariableType::INT64(), iterator, JSObject::HASH_OFFSET,
|
||||
builder_.Int64(JSTaggedValue(0).GetRawData()));
|
||||
builder_.StoreConstOffset(VariableType::INT64(), iterator, JSObject::PROPERTIES_OFFSET, emptyArray);
|
||||
builder_.StoreConstOffset(VariableType::INT64(), iterator, JSObject::ELEMENTS_OFFSET, emptyArray);
|
||||
|
||||
builder_.StoreConstOffset(VariableType::JS_ANY(), iterator, JSArrayIterator::ITERATED_ARRAY_OFFSET, self);
|
||||
builder_.StoreConstOffset(VariableType::INT32(), iterator, JSArrayIterator::NEXT_INDEX_OFFSET, builder_.Int32(0));
|
||||
builder_.StoreConstOffset(VariableType::INT32(), iterator, JSArrayIterator::BIT_FIELD_OFFSET, kind);
|
||||
|
||||
GateRef result = builder_.FinishAllocate(iterator);
|
||||
builder_.SubCfgExit();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void TypedNativeInlineLowering::LowerTypedArrayIterator(GateRef gate, CommonStubCSigns::ID index,
|
||||
IterationKind iterationKind)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
GateRef self = acc_.GetValueIn(gate, 0);
|
||||
|
||||
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
|
||||
|
||||
Label selfExistsLabel(&env);
|
||||
Label isHeapObjectLabel(&env);
|
||||
Label isTypedArrayLabel(&env);
|
||||
Label selfValidLabel(&env);
|
||||
Label selfInvalidLabel(&env);
|
||||
Label exit(&env);
|
||||
|
||||
GateRef selfExists = builder_.TaggedIsNotUndefinedAndNullAndHole(self);
|
||||
BRANCH_CIR(selfExists, &selfExistsLabel, &selfInvalidLabel);
|
||||
builder_.Bind(&selfExistsLabel);
|
||||
|
||||
GateRef isHeapObject = builder_.TaggedIsHeapObject(self);
|
||||
BRANCH_CIR(isHeapObject, &isHeapObjectLabel, &selfInvalidLabel);
|
||||
builder_.Bind(&isHeapObjectLabel);
|
||||
|
||||
GateRef isTypedArray = builder_.IsTypedArray(self);
|
||||
BRANCH_CIR(isTypedArray, &isTypedArrayLabel, &selfInvalidLabel);
|
||||
builder_.Bind(&isTypedArrayLabel);
|
||||
|
||||
GateRef hasNoConstructor = builder_.BoolNot(builder_.HasConstructor(self));
|
||||
BRANCH_CIR(hasNoConstructor, &selfValidLabel, &selfInvalidLabel);
|
||||
builder_.Bind(&selfValidLabel);
|
||||
{
|
||||
GateRef glueGlobalEnvOffset = builder_.IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env.Is32Bit()));
|
||||
GateRef glueGlobalEnv = builder_.Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
|
||||
GateRef prototype = builder_.GetGlobalEnvValue(VariableType::JS_POINTER(), glueGlobalEnv,
|
||||
GlobalEnv::ARRAY_ITERATOR_PROTOTYPE_INDEX);
|
||||
|
||||
GateRef iteratorHClass = builder_.GetGlobalConstantValue(ConstantIndex::JS_ARRAY_ITERATOR_CLASS_INDEX);
|
||||
GateRef offset = builder_.IntPtr(JSHClass::PROTOTYPE_OFFSET);
|
||||
builder_.Store(VariableType::JS_POINTER(), glue, iteratorHClass, offset, prototype);
|
||||
|
||||
result = AllocateTypedArrayIterator(glue, self, iteratorHClass, iterationKind);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
|
||||
builder_.Bind(&selfInvalidLabel);
|
||||
{
|
||||
result = builder_.CallStub(glue, gate, index, { glue, self });
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
GateRef TypedNativeInlineLowering::LowerGlobalDoubleIsFinite(GateRef value)
|
||||
{
|
||||
// set the sign bit to 0 by shift left then right.
|
||||
@ -991,6 +1108,85 @@ void TypedNativeInlineLowering::LowerArrayBufferIsView(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
template <bool IS_UNSIGNED>
|
||||
void TypedNativeInlineLowering::LowerBigIntAsIntN(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
Label hasException(&builder_);
|
||||
Label exit(&builder_);
|
||||
Label returnBigInt(&builder_);
|
||||
Label notZeroBigInt(&builder_);
|
||||
Label commonCase(&builder_);
|
||||
#if BIGINT_CONSTRUCTOR_IMPLEMENTED // NOTE: add fastpath after BigInt constructor implementing
|
||||
Label zeroBits(&builder_);
|
||||
Label notZeroBits(&builder_);
|
||||
#endif // BIGINT_CONSTRUCTOR_IMPLEMENTED
|
||||
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
GateRef bits = acc_.GetValueIn(gate, 0);
|
||||
GateRef bigint = acc_.GetValueIn(gate, 1);
|
||||
GateRef frameState = acc_.GetValueIn(gate, 2);
|
||||
GateRef bitness = builder_.GetDoubleOfTDouble(bits);
|
||||
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
|
||||
|
||||
// Deoptimization if bitness is negative or more than safe number
|
||||
GateRef safeNumber = builder_.Double(SAFE_NUMBER);
|
||||
GateRef positiveCheck = builder_.DoubleGreaterThanOrEqual(bitness, builder_.Double(0));
|
||||
GateRef safeCheck = builder_.DoubleLessThanOrEqual(bitness, safeNumber);
|
||||
builder_.DeoptCheck(positiveCheck, frameState, DeoptType::RANGE_ERROR);
|
||||
builder_.DeoptCheck(safeCheck, frameState, DeoptType::RANGE_ERROR);
|
||||
builder_.DeoptCheck(builder_.TaggedIsBigInt(bigint), frameState, DeoptType::NOT_BIG_INT);
|
||||
|
||||
// Return bigint(0), if bits == 0
|
||||
#if BIGINT_CONSTRUCTOR_IMPLEMENTED // NOTE: add fastpath after BigInt constructor implementing
|
||||
BRANCH_CIR(builder_.DoubleEqual(bitness, builder_.Double(0)), &zeroBits, ¬ZeroBits);
|
||||
builder_.Bind(&zeroBits);
|
||||
{
|
||||
result = builder_.BigIntConstructor(0);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(¬ZeroBits);
|
||||
#endif // BIGINT_CONSTRUCTOR_IMPLEMENTED
|
||||
|
||||
// Return bigint, if bigint == 0
|
||||
GateRef lengthOffset = builder_.IntPtr(BigInt::LENGTH_OFFSET);
|
||||
GateRef length = builder_.Load(VariableType::INT32(), bigint, lengthOffset);
|
||||
GateRef isOneBit = builder_.Int32Equal(length, builder_.Int32(1));
|
||||
|
||||
GateRef dataOffset = builder_.IntPtr(BigInt::DATA_OFFSET);
|
||||
GateRef firstDigit = builder_.Load(VariableType::INT32(), bigint, dataOffset);
|
||||
GateRef isZero = builder_.Int32Equal(firstDigit, builder_.Int32(0));
|
||||
BRANCH_CIR(builder_.BoolAnd(isOneBit, isZero), &returnBigInt, ¬ZeroBigInt);
|
||||
|
||||
// Return bigint, if bits >= max_value
|
||||
builder_.Bind(¬ZeroBigInt);
|
||||
GateRef maxLengthBits = builder_.Double(static_cast<double>(BigInt::kMaxLengthBits));
|
||||
BRANCH_CIR(builder_.DoubleGreaterThanOrEqual(bitness, maxLengthBits), &returnBigInt, &commonCase);
|
||||
builder_.Bind(&returnBigInt);
|
||||
{
|
||||
result = bigint;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
|
||||
// Common case
|
||||
builder_.Bind(&commonCase);
|
||||
if constexpr (IS_UNSIGNED) {
|
||||
result = builder_.CallRuntime(glue, RTSTUB_ID(CallBigIntAsUintN), Gate::InvalidGateRef,
|
||||
{bits, bigint}, gate);
|
||||
} else {
|
||||
result = builder_.CallRuntime(glue, RTSTUB_ID(CallBigIntAsIntN), Gate::InvalidGateRef,
|
||||
{bits, bigint}, gate);
|
||||
}
|
||||
BRANCH_CIR(builder_.HasPendingException(glue), &hasException, &exit);
|
||||
builder_.Bind(&hasException);
|
||||
{
|
||||
result = builder_.ExceptionConstant();
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypedNativeInlineLowering::LowerDataViewProtoFunc(GateRef gate, DataViewProtoFunc func)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
@ -1612,4 +1808,12 @@ void TypedNativeInlineLowering::LowerDateGetTime(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void TypedNativeInlineLowering::LowerGeneralWithoutArgs(GateRef gate, RuntimeStubCSigns::ID stubId)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
GateRef result = builder_.CallNGCRuntime(glue, stubId, Gate::InvalidGateRef, {glue}, gate);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ private:
|
||||
void LowerClz32Int32(GateRef gate);
|
||||
void LowerMathSqrt(GateRef gate);
|
||||
void LowerNewNumber(GateRef gate);
|
||||
template <bool IS_UNSIGNED>
|
||||
void LowerBigIntAsIntN(GateRef gate);
|
||||
GateRef BuildRounding(GateRef gate, GateRef value, OpCode op);
|
||||
void LowerTaggedRounding(GateRef gate);
|
||||
void LowerDoubleRounding(GateRef gate);
|
||||
@ -107,6 +109,10 @@ private:
|
||||
void LowerMathImul(GateRef gate);
|
||||
void LowerGlobalIsFinite(GateRef gate);
|
||||
void LowerGlobalIsNan(GateRef gate);
|
||||
void LowerGeneralWithoutArgs(GateRef gate, RuntimeStubCSigns::ID stubId);
|
||||
GateRef AllocateTypedArrayIterator(GateRef glue, GateRef self,
|
||||
GateRef iteratorHClass, IterationKind iterationKind);
|
||||
void LowerTypedArrayIterator(GateRef gate, CommonStubCSigns::ID index, IterationKind iterationKind);
|
||||
|
||||
GateRef LowerGlobalDoubleIsFinite(GateRef value);
|
||||
GateRef LowerGlobalTNumberIsFinite(GateRef value);
|
||||
@ -124,4 +130,4 @@ private:
|
||||
bool isLiteCG_ {false};
|
||||
};
|
||||
}
|
||||
#endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
|
||||
#endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
|
||||
|
@ -134,6 +134,7 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, JSAPIIteratorFuncHClass, JS_API_ITERATOR_FUNC_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSAPIAsyncIteratorFuncHClass, JS_API_ASYNCITERATOR_FUNC_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ObjectClass, OBJECT_HCLASS_INDEX, initial_object_hclass) \
|
||||
V(JSTaggedValue, JSMapClass, JS_MAP_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, IteratorResultClass, ITERATOR_RESULT_CLASS, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassPrototypeClass, CLASS_PROTOTYPE_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassConstructorClass, CLASS_CONSTRUCTOR_HCLASS_INDEX, ecma_roots_class) \
|
||||
@ -192,11 +193,15 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, MathCeil, MATH_CEIL_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, MathFloor, MATH_FLOOR_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, MathImul, MATH_IMUL_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, BigIntAsIntN, BIGINT_AS_INTN_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, BigIntAsUintN, BIGINT_AS_UINTN_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, GlobalIsFinite, GLOBAL_IS_FINITE_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, GlobalIsNan, GLOBAL_IS_NAN_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, MapGet, MAP_GET_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, MapHas, MAP_HAS_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, SetHas, SET_HAS_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, MapDelete, MAP_DELETE_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, SetDelete, SET_DELETE_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, LocaleCompareFunction, LOCALE_COMPARE_FUNCTION_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, ArraySortFunction, ARRAY_SORT_FUNCTION_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, JsonStringifyFunction, JSON_STRINGIFY_FUNCTION_INDEX, ecma_roots_builtins) \
|
||||
@ -206,6 +211,9 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, ArrayIteratorProtoNext, ARRAY_ITERATOR_PROTO_NEXT_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, IteratorProtoReturn, ITERATOR_PROTO_RETURN_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, StringFromCharCode, STRING_FROM_CHAR_CODE_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, TypedArrayEntries, TYPED_ARRAY_ENTRIES_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, TypedArrayKeys, TYPED_ARRAY_KEYS_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, TypedArrayValues, TYPED_ARRAY_VALUES_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, ArrayBufferIsView, ARRAY_BUFFER_IS_VIEW_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, DataViewGetFloat32, DATA_VIEW_GET_FLOAT32_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, DataViewGetFloat64, DATA_VIEW_GET_FLOAT64_INDEX, ecma_roots_builtins) \
|
||||
@ -224,6 +232,7 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, DataViewSetUint16, DATA_VIEW_SET_UINT16_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, DataViewSetUint32, DATA_VIEW_SET_UINT32_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, DateGetTime, DATE_GET_TIME_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DateNow, DATE_NOW_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, NumberIsNaN, NUMBER_IS_NAN_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, NumberIsFinite, NUMBER_IS_FINITE_INDEX, ecma_roots_builtins) \
|
||||
V(JSTaggedValue, NumberIsInteger, NUMBER_IS_INTEGER_INDEX, ecma_roots_builtins) \
|
||||
@ -233,6 +242,7 @@ class ObjectFactory;
|
||||
#define SHARED_GLOBAL_ENV_CONSTANT_STRING(V) \
|
||||
V(ConstructorString, CONSTRUCTOR_STRING_INDEX, "constructor") \
|
||||
V(PrototypeString, PROTOTYPE_STRING_INDEX, "prototype") \
|
||||
V(SizeString, SIZE_STRING_INDEX, "size") \
|
||||
V(LengthString, LENGTH_STRING_INDEX, "length") \
|
||||
V(ValueString, VALUE_STRING_INDEX, "value") \
|
||||
V(SetString, SET_STRING_INDEX, "set") \
|
||||
|
@ -367,6 +367,15 @@ public:
|
||||
return builtinsArrayId.GetTransitionElementsKind();
|
||||
}
|
||||
|
||||
bool IsBuiltinsMap() const
|
||||
{
|
||||
if (IsBuiltinsType()) {
|
||||
JSType type = GetBuiltinsType();
|
||||
return type == JSType::JS_MAP;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsBuiltinsString() const
|
||||
{
|
||||
if (IsBuiltinsType()) {
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "ecmascript/js_arguments.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
#include "ecmascript/js_async_generator_object.h"
|
||||
#include "ecmascript/js_bigint.h"
|
||||
#include "ecmascript/js_for_in_iterator.h"
|
||||
#include "ecmascript/js_generator_object.h"
|
||||
#include "ecmascript/js_iterator.h"
|
||||
@ -2480,6 +2481,20 @@ JSTaggedValue RuntimeStubs::RuntimeLdBigInt(JSThread *thread, const JSHandle<JST
|
||||
return JSTaggedValue::ToBigInt(thread, numberBigInt);
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeCallBigIntAsIntN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint)
|
||||
{
|
||||
auto biginteger = JSHandle<BigInt>(thread, bigint);
|
||||
JSTaggedNumber bitness = JSTaggedValue::ToNumber(thread, bits);
|
||||
return BigInt::AsintN(thread, bitness, biginteger);
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeCallBigIntAsUintN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint)
|
||||
{
|
||||
auto biginteger = JSHandle<BigInt>(thread, bigint);
|
||||
JSTaggedNumber bitness = JSTaggedValue::ToNumber(thread, bits);
|
||||
return BigInt::AsUintN(thread, bitness, biginteger);
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <cmath>
|
||||
#include <cfenv>
|
||||
#include <sstream>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/log.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
@ -53,6 +55,7 @@
|
||||
#include "ecmascript/interpreter/interpreter_assembly.h"
|
||||
#include "ecmascript/js_api/js_api_arraylist.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_bigint.h"
|
||||
#include "ecmascript/js_date.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_map_iterator.h"
|
||||
@ -2520,6 +2523,22 @@ DEF_RUNTIME_STUBS(LdBigInt)
|
||||
return RuntimeLdBigInt(thread, numberBigInt).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(CallBigIntAsIntN)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(CallBigIntAsIntN);
|
||||
JSTaggedValue bits = GetArg(argv, argc, 0); // 0: means the zeroth parameter
|
||||
JSTaggedValue bigint = GetArg(argv, argc, 1); // 1: means the first parameter
|
||||
return RuntimeCallBigIntAsIntN(thread, bits, bigint).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(CallBigIntAsUintN)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(CallBigIntAsUintN);
|
||||
JSTaggedValue bits = GetArg(argv, argc, 0); // 0: means the zeroth parameter
|
||||
JSTaggedValue bigint = GetArg(argv, argc, 1); // 1: means the first parameter
|
||||
return RuntimeCallBigIntAsUintN(thread, bits, bigint).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(ToNumeric)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(ToNumeric);
|
||||
@ -3062,6 +3081,17 @@ bool RuntimeStubs::NumberIsFinite(double x)
|
||||
return std::isfinite(x);
|
||||
}
|
||||
|
||||
double RuntimeStubs::CallDateNow()
|
||||
{
|
||||
// time from now is in ms.
|
||||
int64_t ans;
|
||||
struct timeval tv {
|
||||
};
|
||||
gettimeofday(&tv, nullptr);
|
||||
ans = static_cast<int64_t>(tv.tv_sec) * MS_PER_SECOND + (tv.tv_usec / MS_PER_SECOND);
|
||||
return static_cast<double>(ans);
|
||||
}
|
||||
|
||||
int32_t RuntimeStubs::DoubleToInt(double x, size_t bits)
|
||||
{
|
||||
return base::NumberHelper::DoubleToInt(x, bits);
|
||||
|
@ -142,6 +142,7 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
|
||||
V(FloatFloor) \
|
||||
V(FloatPow) \
|
||||
V(FloatCeil) \
|
||||
V(CallDateNow) \
|
||||
V(NumberIsFinite) \
|
||||
V(FindElementWithCache) \
|
||||
V(CreateArrayFromList) \
|
||||
@ -353,6 +354,8 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
|
||||
V(LdBigInt) \
|
||||
V(ToNumeric) \
|
||||
V(ToNumericConvertBigInt) \
|
||||
V(CallBigIntAsIntN) \
|
||||
V(CallBigIntAsUintN) \
|
||||
V(DynamicImport) \
|
||||
V(CreateAsyncGeneratorObj) \
|
||||
V(AsyncGeneratorResolve) \
|
||||
@ -513,6 +516,7 @@ public:
|
||||
static double FloatCbrt(double x);
|
||||
static double FloatCeil(double x);
|
||||
static bool NumberIsFinite(double x);
|
||||
static double CallDateNow();
|
||||
static int32_t FindElementWithCache(uintptr_t argGlue, JSTaggedType hclass,
|
||||
JSTaggedType key, int32_t num);
|
||||
static bool StringsAreEquals(EcmaString *str1, EcmaString *str2);
|
||||
@ -802,6 +806,8 @@ private:
|
||||
static inline JSTaggedValue RuntimeThrowReferenceError(JSThread *thread, JSTaggedValue prop, const char *desc);
|
||||
static inline JSTaggedValue RuntimeThrowSyntaxError(JSThread *thread, const char *message);
|
||||
static inline JSTaggedValue RuntimeLdBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &numberBigInt);
|
||||
static inline JSTaggedValue RuntimeCallBigIntAsIntN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint);
|
||||
static inline JSTaggedValue RuntimeCallBigIntAsUintN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint);
|
||||
static inline JSTaggedValue RuntimeNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId);
|
||||
static inline JSTaggedValue RuntimeOptGetUnmapedArgs(JSThread *thread, uint32_t actualNumArgs);
|
||||
static inline JSTaggedValue RuntimeGetUnmapedJSArgumentObj(JSThread *thread,
|
||||
|
@ -159,13 +159,15 @@ def judge_output(args: object):
|
||||
expect_output = ''.join(file.readlines()[13:])
|
||||
file.close()
|
||||
out_str = out.decode('UTF-8', errors="ignore")
|
||||
if out_str != expect_output or returncode != "0":
|
||||
result_cmp = compare_line_by_line(expect_output, out_str)
|
||||
if result_cmp or returncode != "0":
|
||||
print(">>>>> ret <<<<<")
|
||||
print(returncode)
|
||||
print(">>>>> err <<<<<")
|
||||
print(err_str)
|
||||
print(">>>>> Expect : [" + expect_output \
|
||||
+ "]\n>>>>> But got: [" + out_str + "]")
|
||||
print(">>>>> Expect {} lines: [{}]\n>>>>> But got {} lines: [{}]".format(
|
||||
expect_output.count('\n'), expect_output, out_str.count('\n'), out_str
|
||||
))
|
||||
raise RuntimeError("Run [" + cmd + "] failed!")
|
||||
else:
|
||||
raise RuntimeError("Run [" + cmd + "] with no expect !")
|
||||
@ -173,6 +175,37 @@ def judge_output(args: object):
|
||||
print("Run [" + cmd + "] success!")
|
||||
print("used: %.5f seconds" % (time.time() - start_time))
|
||||
|
||||
def compare_line_by_line(expect_output:str, got_output:str):
|
||||
expect_output_list = expect_output.split("\n")
|
||||
got_output_list = got_output.split("\n")
|
||||
for index, (expect_line, got_line) in enumerate(zip(expect_output_list, got_output_list)):
|
||||
if expect_line == got_line:
|
||||
continue
|
||||
error_msg = ""
|
||||
|
||||
if "__INT_MORE_PREV__" in expect_line:
|
||||
prev_got_value = reverse_find_first_not_trace_line(got_output_list, index-1)
|
||||
if got_line.isdigit() and prev_got_value.isdigit() and int(prev_got_value) < int(got_line):
|
||||
continue
|
||||
error_msg = "Got integer result is not more than previous integer result"
|
||||
|
||||
if "__INT__" in expect_line:
|
||||
if got_line.isdigit():
|
||||
continue
|
||||
error_msg = "Got not integer"
|
||||
|
||||
print(">>>>> diff <<<<<")
|
||||
if error_msg:
|
||||
print(error_msg)
|
||||
print("Difference in line {}:\nExcepted: [{}]\nBut got: [{}]".format(index+1, expect_line, got_line))
|
||||
return True
|
||||
return False
|
||||
|
||||
def reverse_find_first_not_trace_line(output_list: list, init_index: int) -> str:
|
||||
for i in range(init_index, -1, -1):
|
||||
if "[trace]" not in output_list[i]:
|
||||
return output_list[i]
|
||||
return ""
|
||||
|
||||
if __name__ == '__main__':
|
||||
input_args = parse_args()
|
||||
|
@ -14,11 +14,13 @@
|
||||
group("ark_aot_builtin_inlining_test") {
|
||||
testonly = true
|
||||
deps = [
|
||||
"bigint:ark_aot_builtin_inlining_bigint_test",
|
||||
"date:ark_aot_builtin_inlining_date_test",
|
||||
"global:ark_aot_builtin_inlining_global_test",
|
||||
"map:ark_aot_builtin_inlining_map_test",
|
||||
"math:ark_aot_builtin_inlining_math_test",
|
||||
"number:ark_aot_builtin_inlining_number_test",
|
||||
"set:ark_aot_builtin_inlining_set_test",
|
||||
"typedarray:ark_aot_builtin_inlining_typedarray_test",
|
||||
]
|
||||
}
|
||||
|
17
test/aottest/builtin_inlining/bigint/AsIntN/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/bigint/AsIntN/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinBigIntAsIntN") {
|
||||
}
|
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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, b)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
function doAsIntN(bits: number, b : bigint) {
|
||||
return BigInt.asIntN(bits, b);
|
||||
}
|
||||
|
||||
function tryDoAsIntN(bits: number, b : bigint) {
|
||||
try {
|
||||
print(doAsIntN(bits, b));
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
function tryDoAsIntNEmpty() {
|
||||
try {
|
||||
print(BigInt.asIntN());
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
function tryDoAsIntNSingle(a) {
|
||||
try {
|
||||
print(BigInt.asIntN(a));
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
function printAsIntN(bits: number, b : bigint) {
|
||||
try {
|
||||
print(doAsIntN(bits, b));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
// Check standart behaviour
|
||||
// 25n = 00011001
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(3, 25n)); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(4, 25n)); //: -7
|
||||
|
||||
// Check without params
|
||||
tryDoAsIntNEmpty(); //: TypeError: Cannot convert a undefine or null value to a BigInt
|
||||
|
||||
// Check with 1 param
|
||||
tryDoAsIntNSingle(16); //: TypeError: Cannot convert a undefine or null value to a BigInt
|
||||
tryDoAsIntNSingle(23n); //: TypeError: Cannot convert a BigInt value to a number
|
||||
|
||||
// Check with 2 params
|
||||
// 100n = 01100100
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(4, 100n)); //: 4
|
||||
|
||||
// Check with 3 params
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(8, 100n, undefined)); //: 100
|
||||
|
||||
// Check with 4 params
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(16, 100n, -20000, "abc")); //: 100
|
||||
|
||||
// Check some corner cases
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(0, 10000n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, 0n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
//aot: [trace] Check Type: RangeError
|
||||
tryDoAsIntN(-2, 10000n); //: RangeError: integerIndex < 0 or integerIndex > SAFE_NUMBER
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
//aot: [trace] Check Type: RangeError
|
||||
tryDoAsIntN(2 ** 53, 100000n); //: RangeError: integerIndex < 0 or integerIndex > SAFE_NUMBER
|
||||
|
||||
// bits > kMaxLengthBits => return bigint
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(2 ** 35, 2n ** 75n)); //: 37778931862957161709568
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(2 ** 35, 65531n)); //: 65531
|
||||
|
||||
// Check maximum and minimum values
|
||||
const max32 = 2n ** (32n - 1n) - 1n; // INT32_MAX = 2147483647
|
||||
const max32_possible_value = 2n ** 32n - 1n; // 11...11b
|
||||
const max64 = 2n ** (64n - 1n) - 1n; // INT64_MAX = 9223372036854775807
|
||||
const max64_possible_value = 2n ** 64n - 1n; // 11...11b
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, max32)); //: 2147483647
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, max32 + 1n)); //: -2147483648
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, max32_possible_value)); //: -1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, max32_possible_value + 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, max64)); //: 9223372036854775807
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, max64 + 1n)); //: -9223372036854775808
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, max64_possible_value)); //: -1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, max64_possible_value + 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, -max32 - 1n)); //: -2147483648
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, -max32 - 2n)); //: 2147483647
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, -max32_possible_value)); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(32, -max32_possible_value - 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, -max64 - 1n)); //: -9223372036854775808
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, -max64 - 2n)); //: 9223372036854775807
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, -max64_possible_value)); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(BigInt.asIntN(64, -max64_possible_value - 1n)); //: 0
|
||||
|
||||
// Replace standard builtin
|
||||
let true_asintn = BigInt.asIntN
|
||||
BigInt.asIntN = replace
|
||||
print(BigInt.asIntN(-1.001, 26n)); //: -1.001
|
||||
BigInt.asIntN = true_asintn
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
printAsIntN(3, 25n); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
print(true_asintn(3, 25n)); //: 1
|
||||
|
||||
// Call standard builtin with non-number param
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
tryDoAsIntN("abc", "abc"); //: SyntaxError: Cannot convert string to a BigInt,because not allow Infinity, decimal points, or exponents
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
printAsIntN("3", 25n); //: 1
|
||||
|
||||
if (ArkTools.isAOTCompiled(printAsIntN)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
BigInt.asIntN = replace
|
||||
}
|
||||
|
||||
printAsIntN(3, 25n); //pgo: 1
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 3
|
||||
|
||||
tryDoAsIntN("abc", "abc"); //pgo: SyntaxError: Cannot convert string to a BigInt,because not allow Infinity, decimal points, or exponents
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: abc
|
||||
|
||||
BigInt.asIntN = true_asintn
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
printAsIntN(3, 25n); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:doAsIntN@builtinBigIntAsIntN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
printAsIntN("abc", "abc");
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
let obj = {
|
||||
valueOf: () => { return 5; }
|
||||
};
|
||||
|
||||
// 25n = 00011001
|
||||
//aot: [trace] aot inline builtin: BigInt.asIntN, caller function name:func_main_0@builtinBigIntAsIntN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
print(BigInt.asIntN(obj, 25n)); //: -7
|
||||
|
||||
function Throwing() {
|
||||
this.value = 5;
|
||||
}
|
||||
Throwing.prototype.valueOf = function() {
|
||||
if (this.value < 0) {
|
||||
throw new Error("negative bitness");
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
let throwingObj = new Throwing();
|
||||
|
||||
try {
|
||||
// 42n = 00101010
|
||||
print(BigInt.asIntN(throwingObj, 42n)); //: 10
|
||||
throwingObj.value = -8;
|
||||
print(BigInt.asIntN(throwingObj, 42n));
|
||||
} catch(e) {
|
||||
print(e); //: Error: negative bitness
|
||||
} finally {
|
||||
// 15n = 00001111
|
||||
print(BigInt.asIntN(obj, 15n)); //: 15
|
||||
}
|
17
test/aottest/builtin_inlining/bigint/AsUintN/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/bigint/AsUintN/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinBigIntAsUintN") {
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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, b)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
function doAsUintN(bits: number, b : bigint) {
|
||||
return BigInt.asUintN(bits, b);
|
||||
}
|
||||
|
||||
function tryDoAsUintNEmpty() {
|
||||
try {
|
||||
print(BigInt.asUintN());
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
function tryDoAsUintNSingle(a) {
|
||||
try {
|
||||
print(BigInt.asUintN(a));
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
function tryDoAsUintN(bits: number, b : bigint) {
|
||||
try {
|
||||
print(doAsUintN(bits, b));
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
function printAsUintN(bits: number, b : bigint) {
|
||||
try {
|
||||
print(doAsUintN(bits, b));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
// Check standart behaviour
|
||||
// 25n = 00011001
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(3, 25n)); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(4, 25n)); //: 9
|
||||
|
||||
// Check without params
|
||||
tryDoAsUintNEmpty(); //: TypeError: Cannot convert a undefine or null value to a BigInt
|
||||
|
||||
// Check with 1 param
|
||||
tryDoAsUintNSingle(15); //: TypeError: Cannot convert a undefine or null value to a BigInt
|
||||
tryDoAsUintNSingle(23n); //: TypeError: Cannot convert a BigInt value to a number
|
||||
|
||||
// Check with 2 params
|
||||
// 100n = 01100100
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(4, 100n)); //: 4
|
||||
|
||||
// Check with 3 params
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(8, 100n, undefined)); //: 100
|
||||
|
||||
// Check with 4 params
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(16, 100n, -20000, "abc")); //: 100
|
||||
|
||||
// Check some corner cases
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(0, 10000n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(32, 0n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
//aot: [trace] Check Type: RangeError
|
||||
tryDoAsUintN(-2, 10000n); //: RangeError: integerIndex < 0 or integerIndex > SAFE_NUMBER
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
//aot: [trace] Check Type: RangeError
|
||||
tryDoAsUintN(2 ** 53, 100000n); //: RangeError: integerIndex < 0 or integerIndex > SAFE_NUMBER
|
||||
|
||||
// bits > kMaxLengthBits => return bigint
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(2 ** 35, 2n ** 75n)); //: 37778931862957161709568
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(2 ** 35, 65531n)); //: 65531
|
||||
|
||||
// Check maximum and minimum values
|
||||
const max32 = 2n ** 32n - 1n; // UINT32_MAX = 4294967295
|
||||
const max64 = 2n ** 64n - 1n; // UINT64_MAX = 18446744073709551615
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(32, max32)); //: 4294967295
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(32, max32 + 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(64, max64)); //: 18446744073709551615
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(64, max64 + 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(32, -max32)); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(32, -max32 - 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(32, -max32 - 2n)); //: 4294967295
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(64, -max64)); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(64, -max64 - 1n)); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(BigInt.asUintN(64, -max64 - 2n)); //: 18446744073709551615
|
||||
|
||||
// Replace standard builtin
|
||||
let true_asUintN = BigInt.asUintN
|
||||
BigInt.asUintN = replace
|
||||
print(BigInt.asUintN(-1.001, 26n)); //: -1.001
|
||||
BigInt.asUintN = true_asUintN
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
printAsUintN(3, 25n); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
print(true_asUintN(3, 25n)); //: 1
|
||||
|
||||
// Call standard builtin with non-number param
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
tryDoAsUintN("abc", "abc"); //: SyntaxError: Cannot convert string to a BigInt,because not allow Infinity, decimal points, or exponents
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
printAsUintN("3", 25n); //: 1
|
||||
|
||||
if (ArkTools.isAOTCompiled(printAsUintN)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
BigInt.asUintN = replace
|
||||
}
|
||||
|
||||
printAsUintN(3, 25n); //pgo: 1
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 3
|
||||
|
||||
tryDoAsUintN("abc", "abc"); //pgo: SyntaxError: Cannot convert string to a BigInt,because not allow Infinity, decimal points, or exponents
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: abc
|
||||
|
||||
BigInt.asUintN = true_asUintN
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
printAsUintN(3, 25n); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:doAsUintN@builtinBigIntAsUintN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
printAsUintN("abc", "abc");
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
let obj = {
|
||||
valueOf: () => { return 5; }
|
||||
};
|
||||
|
||||
// 25n = 00011001
|
||||
//aot: [trace] aot inline builtin: BigInt.asUintN, caller function name:func_main_0@builtinBigIntAsUintN
|
||||
//aot: [trace] Check Type: NotNumber1
|
||||
print(BigInt.asUintN(obj, 25n)); //: 25
|
||||
|
||||
function Throwing() {
|
||||
this.value = 5;
|
||||
}
|
||||
Throwing.prototype.valueOf = function() {
|
||||
if (this.value < 0) {
|
||||
throw new Error("negative bitness");
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
let throwingObj = new Throwing();
|
||||
|
||||
try {
|
||||
// 42n = 00101010
|
||||
print(BigInt.asUintN(throwingObj, 42n)); //: 10
|
||||
throwingObj.value = -8;
|
||||
print(BigInt.asUintN(throwingObj, 42n));
|
||||
} catch(e) {
|
||||
print(e); //: Error: negative bitness
|
||||
} finally {
|
||||
// 15n = 00001111
|
||||
print(BigInt.asUintN(obj, 15n)); //: 15
|
||||
}
|
28
test/aottest/builtin_inlining/bigint/BUILD.gn
Normal file
28
test/aottest/builtin_inlining/bigint/BUILD.gn
Normal 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.
|
||||
|
||||
group("ark_aot_builtin_inlining_bigint_test") {
|
||||
testonly = true
|
||||
test_list = [
|
||||
"AsIntN",
|
||||
"AsUintN",
|
||||
]
|
||||
|
||||
deps = []
|
||||
foreach(test, test_list) {
|
||||
deps += [ "${test}:builtinBigInt${test}AotAction" ]
|
||||
if (!is_debug) {
|
||||
deps += [ "${test}:builtinBigInt${test}AotContextAction" ]
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,10 @@
|
||||
|
||||
group("ark_aot_builtin_inlining_date_test") {
|
||||
testonly = true
|
||||
test_list = [ "GetTime" ]
|
||||
test_list = [
|
||||
"GetTime",
|
||||
"Now",
|
||||
]
|
||||
|
||||
deps = []
|
||||
foreach(test, test_list) {
|
||||
|
17
test/aottest/builtin_inlining/date/Now/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/date/Now/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinDateNow") {
|
||||
}
|
150
test/aottest/builtin_inlining/date/Now/builtinDateNow.ts
Normal file
150
test/aottest/builtin_inlining/date/Now/builtinDateNow.ts
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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()
|
||||
{
|
||||
return 12345;
|
||||
}
|
||||
|
||||
function doDateNowOneParam(x: any): number {
|
||||
return Date.now(x);
|
||||
}
|
||||
|
||||
function doDateWithoutParam(): number {
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
function printDateNowOneParam(x: any) {
|
||||
try {
|
||||
print(doDateNowOneParam(x));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
function printDateNowWithoutParam() {
|
||||
try {
|
||||
print(doDateWithoutParam());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
// Сhecking that the value changes over time
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now()); //: __INT__
|
||||
let delay = 20000000
|
||||
let result1 = 0
|
||||
let result2 = 0
|
||||
while (result1 < delay) {
|
||||
result1++
|
||||
result2 += result1 % 2
|
||||
}
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now()); //: __INT_MORE_PREV__
|
||||
// Need for disable optimization of loop
|
||||
print(result2); //: 10000000
|
||||
|
||||
// Check with parameters more 0
|
||||
// NOTE: We don't check results between that launches, because they are very close
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now(0)); //: __INT__
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now(1, 2)); //: __INT__
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now(3, 4, 5, 6)); //: __INT__
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now({a:10, b:20})); //: __INT__
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(Date.now("abc")); //: __INT__
|
||||
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:doDateWithoutParam@builtinDateNow
|
||||
printDateNowWithoutParam(); //: __INT__
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:doDateNowOneParam@builtinDateNow
|
||||
printDateNowOneParam(2); //: __INT__
|
||||
|
||||
let true_now = Date.now;
|
||||
|
||||
// Check, that copy method without "this" also is inlined
|
||||
//aot: [trace] aot inline builtin: Date.now, caller function name:func_main_0@builtinDateNow
|
||||
print(true_now()); //: __INT__
|
||||
|
||||
if (ArkTools.isAOTCompiled(printDateNowOneParam)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
Date.now = replace;
|
||||
}
|
||||
|
||||
printDateNowWithoutParam(); //pgo: __INT__
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 12345
|
||||
|
||||
printDateNowOneParam(123); //pgo: __INT__
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 12345
|
||||
|
||||
printDateNowOneParam("abc"); //pgo: __INT__
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 12345
|
||||
|
||||
Date.now = true_now
|
||||
|
||||
// Check on replace object Date
|
||||
let true_date = Date
|
||||
|
||||
if (ArkTools.isAOTCompiled(printDateNowWithoutParam)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
Date = {
|
||||
now : function () { return "Now is now"}
|
||||
};
|
||||
}
|
||||
|
||||
printDateNowWithoutParam(); //pgo: __INT__
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: Now is now
|
||||
|
||||
printDateNowOneParam(123); //pgo: __INT__
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: Now is now
|
||||
|
||||
Date = true_date
|
||||
|
||||
let obj = {
|
||||
valueOf: () => { return -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 {
|
||||
//aot: [trace] Check Type: InconsistentHClass6
|
||||
print(Date.now(throwingObj)); //: __INT__
|
||||
throwingObj.value = 10;
|
||||
// Value isn't use
|
||||
print(Date.now(throwingObj)); //: __INT__
|
||||
} catch(e) {
|
||||
print(e);
|
||||
} finally {
|
||||
print(Date.now(obj)); //: __INT__
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
group("ark_aot_builtin_inlining_map_test") {
|
||||
testonly = true
|
||||
test_list = [
|
||||
"Delete",
|
||||
"Entries",
|
||||
"Get",
|
||||
"GetSize",
|
||||
|
17
test/aottest/builtin_inlining/map/Delete/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/map/Delete/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinMapDelete") {
|
||||
}
|
272
test/aottest/builtin_inlining/map/Delete/builtinMapDelete.ts
Normal file
272
test/aottest/builtin_inlining/map/Delete/builtinMapDelete.ts
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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 doDelete(x: any): any {
|
||||
return myMap.delete(x);
|
||||
}
|
||||
|
||||
function printDelete(x: any) {
|
||||
try {
|
||||
print(doDelete(x));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
function printDelete2(x: any, y: any) {
|
||||
try {
|
||||
print(x.delete(y));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
let myMap = new Map([[0, 0], [0.0, 5], [-1, 1], [2.5, -2.5], [NaN, Infinity], [2000, -0.0], [56, "oops"], ["xyz", "12345"], [-3, 1]]);
|
||||
|
||||
// Check without params
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete()); //: false
|
||||
|
||||
// Check with seting element undefined
|
||||
myMap.set(undefined, 42);
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete()); //: true
|
||||
|
||||
// Check with single param
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(0)); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(3)); //: false
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(NaN)); //: true
|
||||
|
||||
// Check with 2 params
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(2000, 0)); //: true
|
||||
|
||||
// Check with 3 params
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(-51, 10.2, 15)); //: false
|
||||
|
||||
// Check after inserting elements
|
||||
myMap.set(2000, 1e-98);
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(2000)); //: true
|
||||
|
||||
// Replace standard builtin
|
||||
let true_delete = myMap.delete
|
||||
myMap.delete = replace
|
||||
// no deopt
|
||||
print(myMap.delete(2.5)); //: 2.5
|
||||
|
||||
myMap.delete = true_delete
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:doDelete@builtinMapDelete
|
||||
printDelete(-1); //: true
|
||||
|
||||
// Call standard builtin with non-number param
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete("abc")); //: false
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete("2.5")); //: false
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete("xyz")); //: true
|
||||
|
||||
if (ArkTools.isAOTCompiled(printDelete)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
myMap.delete = replace
|
||||
}
|
||||
|
||||
printDelete(2.5); //pgo: true
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 2.5
|
||||
|
||||
printDelete("abc"); //pgo: false
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: abc
|
||||
|
||||
myMap.delete = true_delete
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
print("try-block"); //: try-block
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:doDelete@builtinMapDelete
|
||||
printDelete(0); //: false
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:doDelete@builtinMapDelete
|
||||
printDelete("xyz"); //: false
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
let obj = {};
|
||||
obj.valueOf = (() => { return 0; });
|
||||
|
||||
myMap.set(0, 0);
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(obj)); //: false
|
||||
|
||||
function Throwing() {
|
||||
this.value = 2;
|
||||
Throwing.prototype.valueOf = function() {
|
||||
if (this.value > 0) {
|
||||
throw new Error("positive");
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
let throwingObj = new Throwing();
|
||||
myMap.set(2, 4);
|
||||
try {
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(throwingObj)); //: false
|
||||
} catch(e) {
|
||||
print(e);
|
||||
} finally {
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(obj)); //: false
|
||||
}
|
||||
|
||||
// Check after clearing
|
||||
myMap.clear();
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(myMap.delete(2000)); //: false
|
||||
|
||||
let truedelete = Map.prototype.delete;
|
||||
let m = new Map();
|
||||
m.set(1, 2);
|
||||
m.set(2, 4);
|
||||
m.set("ab", 5);
|
||||
m.set("cd", "e");
|
||||
let obj1 = {};
|
||||
m.set(obj1, "obj");
|
||||
|
||||
print("prototype"); //: prototype
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete(1)); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete(2)); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete(3)); //: false
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete("ab")); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete("cd")); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete("x")); //: false
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete(obj1)); //: true
|
||||
|
||||
let obj2 = {};
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete(obj2)); //: false
|
||||
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete()); //: false
|
||||
m.set(undefined, -1);
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapDelete
|
||||
print(m.delete()); //: true
|
||||
|
||||
print("baseline"); //: baseline
|
||||
m.set(10, 20);
|
||||
let m2 = new Map([[1, 2]]);
|
||||
let m3 = new Map([[1, 2]]);
|
||||
let m4 = new Map([[1, 2]]);
|
||||
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m2, 1); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m3, 1); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m4, 1); //: true
|
||||
|
||||
print("case 0"); //: case 0
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
m4.garbage = function(x: any) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing changed
|
||||
m.set(10, 20);
|
||||
m2.set(10, 20);
|
||||
m3.set(10, 20);
|
||||
m4.set(10, 20); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m2, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m3, 10); //: true
|
||||
printDelete2(m4, 10); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
//: true
|
||||
|
||||
print("case 1"); //: case 1
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
m3.delete = function(x: any) {
|
||||
return -x;
|
||||
}
|
||||
}
|
||||
|
||||
m.set(10, 20);
|
||||
m2.set(10, 20);
|
||||
m3.set(10, 20);
|
||||
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(m2, 10); //: true
|
||||
printDelete2(m3, 10); //pgo: true
|
||||
//aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
//aot: -10
|
||||
|
||||
print("case 2"); //: case 2
|
||||
let mimicMap = {
|
||||
delete: truedelete
|
||||
}
|
||||
let mm = new Map([[1, 2]]);
|
||||
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:printDelete2@builtinMapDelete
|
||||
printDelete2(mm, 1); //: true
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
Object.setPrototypeOf(mm, mimicMap);
|
||||
}
|
||||
printDelete2(mm, 1); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
//: false
|
||||
|
||||
print("case 3") //: case 3
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
Map.prototype.delete = function(x: any) {
|
||||
return -x * 10;
|
||||
}
|
||||
}
|
||||
|
||||
m.set(10, 20);
|
||||
m2.set(10, 20);
|
||||
|
||||
printDelete2(m, 10); //pgo: true
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: -100
|
||||
printDelete2(m2, 10); //pgo: true
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: -100
|
@ -109,6 +109,7 @@ print(iter1.next().value); //: undefined
|
||||
|
||||
// Check using after inserting / deleting
|
||||
let iter2 = myMap.entries();
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapEntries
|
||||
myMap.delete(-1);
|
||||
myMap.set(2000, 1e-98);
|
||||
myMap.set("xyz", -100);
|
||||
|
@ -13,6 +13,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
declare interface ArkTools {
|
||||
isAOTCompiled(args: any): boolean;
|
||||
}
|
||||
declare function print(arg:any):string;
|
||||
|
||||
function doSize(): number {
|
||||
@ -40,8 +43,10 @@ try {
|
||||
}
|
||||
|
||||
// Check after deleting elements
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapGetSize
|
||||
myMap.delete(-1);
|
||||
print(myMap.size); //: 6
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapGetSize
|
||||
myMap.delete(-200);
|
||||
print(myMap.size); //: 6
|
||||
|
||||
@ -53,4 +58,17 @@ print(myMap.size); //: 7
|
||||
|
||||
// Check after clearing
|
||||
myMap.clear();
|
||||
print(myMap.size); //: 0
|
||||
print(myMap.size); //: 0
|
||||
|
||||
// Check deoptimization
|
||||
if (ArkTools.isAOTCompiled(printSize)) {
|
||||
// Define 'size' property in 'myMap', which shadows 'prototype.size'
|
||||
Object.defineProperty(myMap, 'size', {
|
||||
value: 42
|
||||
});
|
||||
}
|
||||
|
||||
printSize();
|
||||
//pgo: 0
|
||||
//aot: [trace] Check Type: IsNotMap
|
||||
//aot: 42
|
||||
|
@ -113,6 +113,7 @@ print(iter1.next().value); //: undefined
|
||||
|
||||
// Check using after deleting
|
||||
let iter2 = myMap.keys();
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapKeys
|
||||
myMap.delete(NaN);
|
||||
myMap.set("xyz", -100);
|
||||
for (let key of iter2) {
|
||||
|
@ -113,6 +113,7 @@ print(iter1.next().value); //: undefined
|
||||
|
||||
// Check using after inserting / deleting
|
||||
let iter2 = myMap.values();
|
||||
//aot: [trace] aot inline builtin: Map.delete, caller function name:func_main_0@builtinMapValues
|
||||
myMap.delete(NaN);
|
||||
myMap.set(2000, 1e-98);
|
||||
myMap.set("xyz", -100);
|
||||
|
@ -14,6 +14,7 @@
|
||||
group("ark_aot_builtin_inlining_set_test") {
|
||||
testonly = true
|
||||
test_list = [
|
||||
"Delete",
|
||||
"Entries",
|
||||
"Has",
|
||||
"Values",
|
||||
|
17
test/aottest/builtin_inlining/set/Delete/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/set/Delete/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinSetDelete") {
|
||||
}
|
272
test/aottest/builtin_inlining/set/Delete/builtinSetDelete.ts
Normal file
272
test/aottest/builtin_inlining/set/Delete/builtinSetDelete.ts
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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 doDelete(x: any): any {
|
||||
return mySet.delete(x);
|
||||
}
|
||||
|
||||
function printDelete(x: any) {
|
||||
try {
|
||||
print(doDelete(x));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
function printDelete2(x: any, y: any) {
|
||||
try {
|
||||
print(x.delete(y));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
let mySet = new Set([0, 0.0, -5, 2.5, 1e-78, NaN, "xyz", "12345"]);
|
||||
|
||||
// Check without params
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete()); //: false
|
||||
|
||||
// Check with adding element undefined
|
||||
mySet.add(undefined, 42);
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete()); //: true
|
||||
|
||||
// Check with single param
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(0)); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(3)); //: false
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(NaN)); //: true
|
||||
|
||||
// Check with 2 params
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(-5, 0)); //: true
|
||||
|
||||
// Check with 3 params
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(-51, 10.2, 15)); //: false
|
||||
|
||||
// Check after inserting elements
|
||||
mySet.add(2000);
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(2000)); //: true
|
||||
|
||||
// Replace standard builtin
|
||||
let true_delete = mySet.delete
|
||||
mySet.delete = replace
|
||||
// no deopt
|
||||
print(mySet.delete(2.5)); //: 2.5
|
||||
|
||||
mySet.delete = true_delete
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:doDelete@builtinSetDelete
|
||||
printDelete(1e-78); //: true
|
||||
|
||||
// Call standard builtin with non-number param
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete("abc")); //: false
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete("2.5")); //: false
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete("xyz")); //: true
|
||||
|
||||
if (ArkTools.isAOTCompiled(printDelete)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
mySet.delete = replace
|
||||
}
|
||||
|
||||
printDelete(2.5); //pgo: true
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: 2.5
|
||||
|
||||
printDelete("abc"); //pgo: false
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: abc
|
||||
|
||||
mySet.delete = true_delete
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
print("try-block"); //: try-block
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:doDelete@builtinSetDelete
|
||||
printDelete(0); //: false
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:doDelete@builtinSetDelete
|
||||
printDelete("xyz"); //: false
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
let obj = {};
|
||||
obj.valueOf = (() => { return 0; });
|
||||
|
||||
mySet.add(0, 0);
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(obj)); //: false
|
||||
|
||||
function Throwing() {
|
||||
this.value = 2;
|
||||
Throwing.prototype.valueOf = function() {
|
||||
if (this.value > 0) {
|
||||
throw new Error("positive");
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
let throwingObj = new Throwing();
|
||||
mySet.add(2);
|
||||
try {
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(throwingObj)); //: false
|
||||
} catch(e) {
|
||||
print(e);
|
||||
} finally {
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(obj)); //: false
|
||||
}
|
||||
|
||||
// Check after clearing
|
||||
mySet.clear();
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(mySet.delete(2000)); //: false
|
||||
|
||||
let truedelete = Set.prototype.delete;
|
||||
let m = new Set();
|
||||
m.add(1);
|
||||
m.add(2);
|
||||
m.add("ab");
|
||||
m.add("cd");
|
||||
let obj1 = {};
|
||||
m.add(obj1);
|
||||
|
||||
print("prototype"); //: prototype
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete(1)); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete(2)); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete(3)); //: false
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete("ab")); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete("cd")); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete("x")); //: false
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete(obj1)); //: true
|
||||
|
||||
let obj2 = {};
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete(obj2)); //: false
|
||||
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete()); //: false
|
||||
m.add(undefined, -1);
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetDelete
|
||||
print(m.delete()); //: true
|
||||
|
||||
print("baseline"); //: baseline
|
||||
m.add(10);
|
||||
let m2 = new Set([1]);
|
||||
let m3 = new Set([1]);
|
||||
let m4 = new Set([1]);
|
||||
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m2, 1); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m3, 1); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m4, 1); //: true
|
||||
|
||||
print("case 0") //: case 0
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
m4.garbage = function(x: any) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing changed
|
||||
m.add(10);
|
||||
m2.add(10);
|
||||
m3.add(10);
|
||||
m4.add(10); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m2, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m3, 10); //: true
|
||||
printDelete2(m4, 10); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
//: true
|
||||
|
||||
print("case 1") //: case 1
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
m3.delete = function(x: any) {
|
||||
return -x;
|
||||
}
|
||||
}
|
||||
|
||||
m.add(10);
|
||||
m2.add(10);
|
||||
m3.add(10);
|
||||
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m, 10); //: true
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(m2, 10); //: true
|
||||
printDelete2(m3, 10); //pgo: true
|
||||
//aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
//aot: -10
|
||||
|
||||
print("case 2") //: case 2
|
||||
let mimicset = {
|
||||
delete: truedelete
|
||||
}
|
||||
let mm = new Set([1]);
|
||||
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:printDelete2@builtinSetDelete
|
||||
printDelete2(mm, 1) //: true
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
Object.setPrototypeOf(mm, mimicset)
|
||||
}
|
||||
printDelete2(mm, 1); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
//: false
|
||||
|
||||
print("case 3"); //: case 3
|
||||
if (ArkTools.isAOTCompiled(printDelete2)) {
|
||||
Set.prototype.delete = function(x: any) {
|
||||
return -x * 10;
|
||||
}
|
||||
}
|
||||
|
||||
m.add(10);
|
||||
m2.add(10);
|
||||
|
||||
printDelete2(m, 10); //pgo: true
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: -100
|
||||
printDelete2(m2, 10); //pgo: true
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
//aot: -100
|
@ -114,9 +114,11 @@ print(iter1.next().value);
|
||||
|
||||
// Check using after inserting / deleting
|
||||
let iter2 = mySet.entries();
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetEntries
|
||||
mySet.delete(5);
|
||||
mySet.add(30);
|
||||
mySet.add(NaN);
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetEntries
|
||||
mySet.delete("12345");
|
||||
for (let key of iter2) {
|
||||
print(key);
|
||||
|
@ -113,9 +113,11 @@ print(iter1.next().value); //: undefined
|
||||
|
||||
// Check using after inserting / deleting
|
||||
let iter2 = mySet.values();
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetValues
|
||||
mySet.delete(5);
|
||||
mySet.add(30);
|
||||
mySet.add(NaN);
|
||||
//aot: [trace] aot inline builtin: Set.delete, caller function name:func_main_0@builtinSetValues
|
||||
mySet.delete("12345");
|
||||
for (let key of iter2) {
|
||||
print(key);
|
||||
|
29
test/aottest/builtin_inlining/typedarray/BUILD.gn
Normal file
29
test/aottest/builtin_inlining/typedarray/BUILD.gn
Normal 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.
|
||||
|
||||
group("ark_aot_builtin_inlining_typedarray_test") {
|
||||
testonly = true
|
||||
test_list = [
|
||||
"Entries",
|
||||
"Keys",
|
||||
"Values",
|
||||
]
|
||||
|
||||
deps = []
|
||||
foreach(test, test_list) {
|
||||
deps += [ "${test}:builtinTypedArray${test}AotAction" ]
|
||||
if (!is_debug) {
|
||||
deps += [ "${test}:builtinTypedArray${test}AotContextAction" ]
|
||||
}
|
||||
}
|
||||
}
|
17
test/aottest/builtin_inlining/typedarray/Entries/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/typedarray/Entries/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinTypedArrayEntries") {
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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: any)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
function getItems(x: any) {
|
||||
return myArray.entries(x);
|
||||
}
|
||||
|
||||
function printItems(x: any) {
|
||||
try {
|
||||
print(getItems(x));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
let myArray = new Uint8Array([10, 20, 30]);
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
let items0 = myArray.entries();
|
||||
print(items0); //: [object Array Iterator]
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
let items1 = myArray.entries();
|
||||
print(items1.next().value); //: 0,10
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
let items2 = myArray.entries();
|
||||
items2.next();
|
||||
print(items2.next().value); //: 1,20
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
let items3 = myArray.entries();
|
||||
items3.next();
|
||||
items3.next();
|
||||
print(items3.next().value); //: 2,30
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
let items4 = myArray.entries();
|
||||
items4.next();
|
||||
items4.next();
|
||||
items4.next();
|
||||
print(items4.next().value); //: undefined
|
||||
|
||||
// Check own methods
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
print(myArray.entries().throw); //: function throw() { [native code] }
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
print(myArray.entries().return); //: function return() { [native code] }
|
||||
|
||||
// Check using in loop
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
for (let item of myArray.entries()) {
|
||||
print(item);
|
||||
}
|
||||
//: 0,10
|
||||
//: 1,20
|
||||
//: 2,30
|
||||
|
||||
// Replace standard builtin
|
||||
let restore = myArray.entries
|
||||
myArray.entries = replace
|
||||
|
||||
// no deopt
|
||||
print(myArray.entries(2.5)); //: 2.5
|
||||
myArray.entries = restore
|
||||
|
||||
if (ArkTools.isAOTCompiled(printItems)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
myArray.entries = replace
|
||||
}
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems(2.5); //aot: 2.5
|
||||
//pgo: [object Array Iterator]
|
||||
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems("abc"); //aot: abc
|
||||
//pgo: [object Array Iterator]
|
||||
|
||||
myArray.entries = restore
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems(2.5); //: [object Array Iterator]
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems("abc"); //: [object Array Iterator]
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
// Check using out of boundaries
|
||||
//aot: [trace] aot inline builtin: TypedArray.entries, caller function name:func_main_0@builtinTypedArrayEntries
|
||||
let items5 = myArray.entries();
|
||||
for (let item of items5) {
|
||||
print(item);
|
||||
}
|
||||
//: 0,10
|
||||
//: 1,20
|
||||
//: 2,30
|
||||
|
||||
// Check reusing possibility
|
||||
for (let item of items5) {
|
||||
print(item);
|
||||
} // <nothing>
|
||||
|
||||
print(items5.next().value); //: undefined
|
17
test/aottest/builtin_inlining/typedarray/Keys/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/typedarray/Keys/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinTypedArrayKeys") {
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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: any)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
function getItems(x: any) {
|
||||
return myArray.keys(x);
|
||||
}
|
||||
|
||||
function printItems(x: any) {
|
||||
try {
|
||||
print(getItems(x));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
let myArray = new Uint8Array([10, 20, 30]);
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
let items0 = myArray.keys();
|
||||
print(items0); //: [object Array Iterator]
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
let items1 = myArray.keys();
|
||||
print(items1.next().value); //: 0
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
let items2 = myArray.keys();
|
||||
items2.next();
|
||||
print(items2.next().value); //: 1
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
let items3 = myArray.keys();
|
||||
items3.next();
|
||||
items3.next();
|
||||
print(items3.next().value); //: 2
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
let items4 = myArray.keys();
|
||||
items4.next();
|
||||
items4.next();
|
||||
items4.next();
|
||||
print(items4.next().value); //: undefined
|
||||
|
||||
// Check own methods
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
print(myArray.keys().throw); //: function throw() { [native code] }
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
print(myArray.keys().return); //: function return() { [native code] }
|
||||
|
||||
// Check using in loop
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
for (let item of myArray.keys()) {
|
||||
print(item);
|
||||
}
|
||||
//: 0
|
||||
//: 1
|
||||
//: 2
|
||||
|
||||
// Replace standard builtin
|
||||
let restore = myArray.keys
|
||||
myArray.keys = replace
|
||||
|
||||
// no deopt
|
||||
print(myArray.keys(2.5)); //: 2.5
|
||||
myArray.keys = restore
|
||||
|
||||
if (ArkTools.isAOTCompiled(printItems)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
myArray.keys = replace
|
||||
}
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems(2.5); //aot: 2.5
|
||||
//pgo: [object Array Iterator]
|
||||
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems("abc"); //aot: abc
|
||||
//pgo: [object Array Iterator]
|
||||
|
||||
myArray.keys = restore
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems(2.5); //: [object Array Iterator]
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems("abc"); //: [object Array Iterator]
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
// Check using out of boundaries
|
||||
//aot: [trace] aot inline builtin: TypedArray.keys, caller function name:func_main_0@builtinTypedArrayKeys
|
||||
let items5 = myArray.keys();
|
||||
for (let item of items5) {
|
||||
print(item);
|
||||
}
|
||||
//: 0
|
||||
//: 1
|
||||
//: 2
|
||||
|
||||
// Check reusing possibility
|
||||
for (let item of items5) {
|
||||
print(item);
|
||||
} // <nothing>
|
||||
|
||||
print(items5.next().value); //: undefined
|
17
test/aottest/builtin_inlining/typedarray/Values/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/typedarray/Values/BUILD.gn
Normal 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinTypedArrayValues") {
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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: any)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
function getItems(x: any) {
|
||||
return myArray.values(x);
|
||||
}
|
||||
|
||||
function printItems(x: any) {
|
||||
try {
|
||||
print(getItems(x));
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
let myArray = new Uint8Array([10, 20, 30]);
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
let items0 = myArray.values();
|
||||
print(items0); //: [object Array Iterator]
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
let items1 = myArray.values();
|
||||
print(items1.next().value); //: 10
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
let items2 = myArray.values();
|
||||
items2.next();
|
||||
print(items2.next().value); //: 20
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
let items3 = myArray.values();
|
||||
items3.next();
|
||||
items3.next();
|
||||
print(items3.next().value); //: 30
|
||||
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
let items4 = myArray.values();
|
||||
items4.next();
|
||||
items4.next();
|
||||
items4.next();
|
||||
print(items4.next().value); //: undefined
|
||||
|
||||
// Check own methods
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
print(myArray.values().throw); //: function throw() { [native code] }
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
print(myArray.values().return); //: function return() { [native code] }
|
||||
|
||||
// Check using in loop
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
for (let item of myArray.values()) {
|
||||
print(item);
|
||||
}
|
||||
//: 10
|
||||
//: 20
|
||||
//: 30
|
||||
|
||||
// Replace standard builtin
|
||||
let restore = myArray.values
|
||||
myArray.values = replace
|
||||
|
||||
// no deopt
|
||||
print(myArray.values(2.5)); //: 2.5
|
||||
myArray.values = restore
|
||||
|
||||
if (ArkTools.isAOTCompiled(printItems)) {
|
||||
// Replace standard builtin after call to standard builtin was profiled
|
||||
myArray.values = replace
|
||||
}
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems(2.5); //aot: 2.5
|
||||
//pgo: [object Array Iterator]
|
||||
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems("abc"); //aot: abc
|
||||
//pgo: [object Array Iterator]
|
||||
|
||||
myArray.values = restore
|
||||
|
||||
// Check IR correctness inside try-block
|
||||
try {
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems(2.5); //: [object Array Iterator]
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
printItems("abc"); //: [object Array Iterator]
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
// Check using out of boundaries
|
||||
//aot: [trace] aot inline builtin: TypedArray.values, caller function name:func_main_0@builtinTypedArrayValues
|
||||
let items5 = myArray.values();
|
||||
for (let item of items5) {
|
||||
print(item);
|
||||
}
|
||||
//: 10
|
||||
//: 20
|
||||
//: 30
|
||||
|
||||
// Check reusing possibility
|
||||
for (let item of items5) {
|
||||
print(item);
|
||||
} // <nothing>
|
||||
|
||||
print(items5.next().value); //: undefined
|
Loading…
x
Reference in New Issue
Block a user