Implement BigInt.asIntN and BigInt.asUintN builtins inlining

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9E7PU
Test: build
Signed-off-by: Oberman Igor <oberman.igor@huawei-partners.com>
Change-Id: I7e6be18965672f80d7dc8921933953e6165834a4
This commit is contained in:
Oberman Igor 2024-04-06 05:10:17 +08:00 committed by Ishin Pavel
parent db1eb53581
commit 699b8fa4e3
25 changed files with 775 additions and 8 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");

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

@ -236,6 +236,8 @@ namespace panda::ecmascript::kungfu {
V(GlobalIsFinite) \
V(GlobalIsNan) \
V(ArrayBufferIsView) \
V(BigIntAsIntN) \
V(BigIntAsUintN) \
V(DataViewGetFloat32) \
V(DataViewGetFloat64) \
V(DataViewGetInt8) \
@ -512,6 +514,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:
@ -568,6 +574,8 @@ public:
{DateNow, "Date.now"},
{GlobalIsFinite, "isFinite"},
{GlobalIsNan, "isNan"},
{BigIntAsIntN, "BigInt.asIntN"},
{BigIntAsUintN, "BigInt.asUintN"},
{MapGet, "Map.get"},
{MapHas, "Map.has"},
{SetHas, "Set.has"},
@ -622,6 +630,8 @@ public:
{"now", DateNow},
{"isFinite", GlobalIsFinite},
{"isNan", GlobalIsNan},
{"asIntN", BigIntAsIntN},
{"asUintN", BigIntAsUintN},
};
if (str2BuiltinId.count(idStr) > 0) {
return str2BuiltinId.at(idStr);

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

View File

@ -432,6 +432,8 @@ private:
V(StringsAreEquals) \
V(BigIntEquals) \
V(BigIntSameValueZero) \
V(CallBigIntAsIntN) \
V(CallBigIntAsUintN) \
V(Dump) \
V(DebugDump) \
V(DumpWithHint) \

View File

@ -646,6 +646,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);

View File

@ -1780,6 +1780,19 @@ 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::IsASCIICharacter(GateRef gate)
{
return Int32UnsignedLessThan(Int32Sub(gate, Int32(1)), Int32(base::utf_helper::UTF8_1B_MAX));

View File

@ -117,6 +117,8 @@ 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) \

View File

@ -221,6 +221,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;
@ -357,6 +361,30 @@ 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::TryInlineMathUnaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
const GateMetaData* op, bool skipThis)
{

View File

@ -64,6 +64,7 @@ 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,

View File

@ -241,6 +241,9 @@ 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:
return VisitOthers(gate, GateType::BooleanType());
@ -1722,6 +1725,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);

View File

@ -99,6 +99,7 @@ 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);

View File

@ -115,6 +115,8 @@ 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(IsNotEcmaObject, ISNOTECMAOBJECT) \
V(IsNotDataView, ISNOTDATAVIEW) \

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"
@ -185,6 +186,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;
@ -994,6 +1001,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_);

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);
@ -125,4 +127,4 @@ private:
bool isLiteCG_ {false};
};
}
#endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
#endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H

View File

@ -192,6 +192,8 @@ 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) \

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

@ -55,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"
@ -2522,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);

View File

@ -354,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) \
@ -804,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

@ -14,6 +14,7 @@
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",

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