!7018 Devbranch for DateNow, BigInt, Map, Set, TypedArray

Merge pull request !7018 from Ishin Pavel/dev_branch_map_set
This commit is contained in:
openharmony_ci 2024-04-20 09:10:14 +00:00 committed by Gitee
commit 1c77da3d0e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
72 changed files with 2760 additions and 25 deletions

View File

@ -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,

View File

@ -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

View File

@ -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 ] ] ] ] ] ] ) */ \

View File

@ -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)

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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: {

View File

@ -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

View File

@ -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) \

View File

@ -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);

View File

@ -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) \
{ \

View File

@ -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()

View File

@ -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) \

View File

@ -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));

View File

@ -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));

View File

@ -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) \

View File

@ -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_);

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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()) {

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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>

View File

@ -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) \

View File

@ -977,6 +977,11 @@ public:
return types_.size();
}
bool IsBuiltinsMap() const
{
return types_[0].IsBuiltinsMap();
}
bool IsBuiltinsString() const
{
return types_[0].IsBuiltinsString();

View File

@ -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)
{

View File

@ -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);

View File

@ -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_);

View File

@ -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);

View File

@ -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, &notZeroBits);
builder_.Bind(&zeroBits);
{
result = builder_.BigIntConstructor(0);
builder_.Jump(&exit);
}
builder_.Bind(&notZeroBits);
#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, &notZeroBigInt);
// Return bigint, if bits >= max_value
builder_.Bind(&notZeroBigInt);
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);
}
}

View File

@ -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

View File

@ -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") \

View File

@ -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()) {

View File

@ -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();

View File

@ -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);

View File

@ -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,

View File

@ -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()

View File

@ -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",
]
}

View File

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

View File

@ -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
}

View File

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

View File

@ -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
}

View File

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

View File

@ -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) {

View File

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

View 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__
}

View File

@ -14,6 +14,7 @@
group("ark_aot_builtin_inlining_map_test") {
testonly = true
test_list = [
"Delete",
"Entries",
"Get",
"GetSize",

View File

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

View 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

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -14,6 +14,7 @@
group("ark_aot_builtin_inlining_set_test") {
testonly = true
test_list = [
"Delete",
"Entries",
"Has",
"Values",

View File

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

View 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

View File

@ -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);

View File

@ -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);

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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