mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
Support BigIntConstructor inlint
Co-author: Andrey Efremov <efremov.andrey@huawei-partners.com> Signed-off-by: Chernykh Sergey <chernykh.sergey1@huawei.com>
This commit is contained in:
parent
66146b68a0
commit
93eb2a8add
@ -799,8 +799,8 @@ void Builtins::InitializeBigInt(const JSHandle<GlobalEnv> &env, const JSHandle<J
|
||||
factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, bigIntFuncPrototypeValue);
|
||||
// BigInt = new Function()
|
||||
JSHandle<JSObject> bigIntFunction(
|
||||
NewBuiltinConstructor(env, bigIntFuncPrototype,
|
||||
BuiltinsBigInt::BigIntConstructor, "BigInt", FunctionLength::ONE));
|
||||
NewBuiltinConstructor(env, bigIntFuncPrototype, BuiltinsBigInt::BigIntConstructor, "BigInt",
|
||||
FunctionLength::ONE, kungfu::BuiltinsStubCSigns::BigIntConstructor));
|
||||
JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
|
||||
JSHandle<JSFunction>(bigIntFunction),
|
||||
bigIntFuncInstanceHClass.GetTaggedValue());
|
||||
|
@ -38,6 +38,13 @@ JSTaggedValue BuiltinsBigInt::BigIntConstructor(EcmaRuntimeCallInfo *argv)
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "BigInt is not a constructor", JSTaggedValue::Exception());
|
||||
}
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
return BigIntConstructorInternal(thread, value);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsBigInt::BigIntConstructorInternal(JSThread *thread, JSHandle<JSTaggedValue> value)
|
||||
{
|
||||
BUILTINS_API_TRACE(thread, BigInt, Constructor);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 2. Let prim be ? ToPrimitive(value).
|
||||
JSHandle<JSTaggedValue> Primitive(thread, JSTaggedValue::ToPrimitive(thread, value));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
@ -45,6 +45,7 @@ class BuiltinsBigInt : public base::BuiltinsBase {
|
||||
public:
|
||||
// 21.2.1.1
|
||||
static JSTaggedValue BigIntConstructor(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue BigIntConstructorInternal(JSThread *thread, JSHandle<JSTaggedValue> value);
|
||||
// 21.2.2.1
|
||||
static JSTaggedValue AsIntN(EcmaRuntimeCallInfo *argv);
|
||||
// 21.2.2.2
|
||||
|
@ -69,6 +69,8 @@ size_t BuiltinsStubCSigns::GetGlobalEnvIndex(ID builtinId)
|
||||
switch (builtinId) {
|
||||
case BuiltinsStubCSigns::ID::NumberConstructor:
|
||||
return static_cast<size_t>(GlobalEnvField::NUMBER_FUNCTION_INDEX);
|
||||
case BuiltinsStubCSigns::ID::BigIntConstructor:
|
||||
return static_cast<size_t>(GlobalEnvField::BIGINT_FUNCTION_INDEX);
|
||||
default:
|
||||
LOG_COMPILER(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
|
@ -238,6 +238,7 @@ namespace panda::ecmascript::kungfu {
|
||||
V(DateNow) \
|
||||
V(GlobalIsFinite) \
|
||||
V(GlobalIsNan) \
|
||||
V(BigIntConstructor) \
|
||||
V(ArrayBufferIsView) \
|
||||
V(BigIntAsIntN) \
|
||||
V(BigIntAsUintN) \
|
||||
@ -628,6 +629,7 @@ public:
|
||||
{SetHas, "Set.has"},
|
||||
{MapDelete, "Map.delete"},
|
||||
{SetDelete, "Set.delete"},
|
||||
{BigIntConstructor, "BigInt"},
|
||||
};
|
||||
if (builtinId2Str.count(id) > 0) {
|
||||
return builtinId2Str.at(id);
|
||||
@ -683,6 +685,7 @@ public:
|
||||
{"asUintN", BigIntAsUintN},
|
||||
{"mapDelete", MapDelete},
|
||||
{"setDelete", SetDelete},
|
||||
{"BigInt", BigIntConstructor},
|
||||
};
|
||||
if (str2BuiltinId.count(idStr) > 0) {
|
||||
return str2BuiltinId.at(idStr);
|
||||
|
@ -194,6 +194,7 @@ GateRef BuiltinLowering::LowerCallTargetCheck(Environment *env, GateRef gate)
|
||||
case BuiltinsStubCSigns::ID::TypeArrayProtoIterator: {
|
||||
return LowerCallTargetCheckWithDetector(gate, id);
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::BigIntConstructor:
|
||||
case BuiltinsStubCSigns::ID::NumberConstructor: {
|
||||
return LowerCallTargetCheckWithGlobalEnv(gate, id);
|
||||
}
|
||||
|
@ -269,8 +269,8 @@ void LLVMIRBuilder::Build()
|
||||
continue;
|
||||
}
|
||||
if (illegalOpHandlers_.find(acc_.GetOpCode(gate)) == illegalOpHandlers_.end()) {
|
||||
LOG_COMPILER(FATAL) << "The gate below need to be translated ";
|
||||
acc_.Print(gate);
|
||||
LOG_COMPILER(FATAL) << "The gate below need to be translated ";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +119,9 @@ namespace panda::ecmascript::kungfu {
|
||||
V(NewNumber, NEW_NUMBER, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(GlobalIsFinite, GLOBAL_IS_FINITE, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(GlobalIsNan, GLOBAL_IS_NAN, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(BigIntConstructor, BIGINT_CONSTRUCTOR, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(BigIntConstructorInt32, BIGINT_CONSTRUCTOR_INT32, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(BigIntConstructorUint32, BIGINT_CONSTRUCTOR_UINT32, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
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) \
|
||||
|
@ -274,6 +274,9 @@ void NativeInlineLowering::RunNativeInlineLowering()
|
||||
case BuiltinsStubCSigns::ID::SetEntries:
|
||||
InlineStubBuiltin(gate, 0U, argc, id, circuit_->SetEntries(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::BigIntConstructor:
|
||||
TryInlineBigIntConstructor(gate, argc, skipThis);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -716,6 +719,7 @@ void NativeInlineLowering::InlineStubBuiltin(GateRef gate, size_t builtinArgc, s
|
||||
if (EnableTrace()) {
|
||||
AddTraceLogs(gate, id);
|
||||
}
|
||||
|
||||
std::vector<GateRef> args {};
|
||||
for (size_t i = 0; i <= builtinArgc; i++) {
|
||||
args.push_back(i <= realArgc ? acc_.GetValueIn(gate, i) : builder_.Undefined());
|
||||
@ -724,6 +728,50 @@ void NativeInlineLowering::InlineStubBuiltin(GateRef gate, size_t builtinArgc, s
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::ReplaceGateWithPendingException(GateRef hirGate, GateRef value)
|
||||
{
|
||||
GateRef state = builder_.GetState();
|
||||
// copy depend-wire of hirGate to value
|
||||
GateRef depend = builder_.GetDepend();
|
||||
// exception value
|
||||
GateRef exceptionVal = builder_.ExceptionConstant();
|
||||
// compare with trampolines result
|
||||
GateRef equal = builder_.Equal(value, exceptionVal);
|
||||
auto ifBranch = builder_.Branch(state, equal, 1, BranchWeight::DEOPT_WEIGHT, "checkException");
|
||||
|
||||
GateRef ifTrue = builder_.IfTrue(ifBranch);
|
||||
GateRef ifFalse = builder_.IfFalse(ifBranch);
|
||||
GateRef eDepend = builder_.DependRelay(ifTrue, depend);
|
||||
GateRef sDepend = builder_.DependRelay(ifFalse, depend);
|
||||
StateDepend success(ifFalse, sDepend);
|
||||
StateDepend exception(ifTrue, eDepend);
|
||||
acc_.ReplaceHirWithIfBranch(hirGate, success, exception, value);
|
||||
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineBigIntConstructor(GateRef gate, size_t argc, bool skipThis)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
bool firstParam = skipThis ? 1 : 0;
|
||||
auto id = BuiltinsStubCSigns::ID::BigIntConstructor;
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
|
||||
builder_.IntPtr(static_cast<int64_t>(id)));
|
||||
}
|
||||
if (EnableTrace()) {
|
||||
AddTraceLogs(gate, id);
|
||||
}
|
||||
|
||||
auto param = builder_.Undefined();
|
||||
if (argc > 0) {
|
||||
param = acc_.GetValueIn(gate, firstParam);
|
||||
}
|
||||
|
||||
GateRef ret = builder_.BuildControlDependOp(circuit_->BigIntConstructor(), {param});
|
||||
ReplaceGateWithPendingException(gate, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineDateGetTime(GateRef gate, size_t argc, bool skipThis)
|
||||
{
|
||||
// Always shout be "this", we can't inline this function without instance of object
|
||||
|
@ -74,6 +74,8 @@ private:
|
||||
void TryInlineWhitoutParamBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
|
||||
const GateMetaData* op, bool skipThis);
|
||||
|
||||
void TryInlineBigIntConstructor(GateRef gate, size_t argc, bool skipThis);
|
||||
void ReplaceGateWithPendingException(GateRef hirGate, GateRef value);
|
||||
void AddTraceLogs(GateRef gate, BuiltinsStubCSigns::ID id);
|
||||
|
||||
bool EnableLog() const
|
||||
|
@ -253,6 +253,8 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
return VisitOthers(gate, GateType::BooleanType());
|
||||
case OpCode::DATE_NOW:
|
||||
return VisitDateNow(gate);
|
||||
case OpCode::BIGINT_CONSTRUCTOR:
|
||||
return VisitBigIntConstructor(gate);
|
||||
case OpCode::JS_BYTECODE:
|
||||
case OpCode::RUNTIME_CALL:
|
||||
case OpCode::PRIMITIVE_TYPE_CHECK:
|
||||
@ -1855,6 +1857,44 @@ GateRef NumberSpeculativeRetype::VisitDataViewGet(GateRef gate)
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitBigIntConstructor(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
return SetOutputType(gate, GateType::BigIntType());
|
||||
}
|
||||
GateRef input = acc_.GetValueIn(gate, 0);
|
||||
TypeInfo typeInfo = GetOutputTypeInfo(input);
|
||||
const GateMetaData* meta = nullptr;
|
||||
switch (typeInfo) {
|
||||
case TypeInfo::INT32:
|
||||
meta = circuit_->BigIntConstructorInt32();
|
||||
break;
|
||||
case TypeInfo::UINT32:
|
||||
meta = circuit_->BigIntConstructorUint32();
|
||||
break;
|
||||
default:
|
||||
auto int32_cnst = TryConvertConstant(input, true);
|
||||
if (int32_cnst != Circuit::NullGate()) {
|
||||
acc_.ReplaceValueIn(gate, int32_cnst, 0);
|
||||
int32_t rawValue = acc_.GetInt32FromConstant(int32_cnst);
|
||||
if (rawValue < 0) {
|
||||
meta = circuit_->BigIntConstructorInt32();
|
||||
} else {
|
||||
meta = circuit_->BigIntConstructorUint32();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (meta != nullptr) {
|
||||
// int or uint input
|
||||
acc_.SetMetaData(gate, meta);
|
||||
} else {
|
||||
// double, object or some other input
|
||||
acc_.ReplaceValueIn(gate, ConvertToTagged(input), 0);
|
||||
}
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitDataViewSet(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
|
@ -113,6 +113,7 @@ private:
|
||||
GateRef VisitDataViewGet(GateRef gate);
|
||||
GateRef VisitDataViewSet(GateRef gate);
|
||||
GateRef VisitOthers(GateRef gate, GateType outputType = GateType::AnyType());
|
||||
GateRef VisitBigIntConstructor(GateRef gate);
|
||||
GateRef VisitTypeConvert(GateRef gate);
|
||||
GateRef VisitFrameState(GateRef gate);
|
||||
GateRef VisitIsTrueOrFalse(GateRef gate);
|
||||
|
@ -74,7 +74,8 @@ bool PostSchedule::VisitHeapAlloc(GateRef gate, ControlFlowGraph &cfg, size_t bb
|
||||
{
|
||||
int64_t flag = acc_.TryGetValue(gate);
|
||||
ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE ||
|
||||
flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE);
|
||||
flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE ||
|
||||
flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE);
|
||||
std::vector<GateRef> currentBBGates;
|
||||
std::vector<GateRef> successBBGates;
|
||||
std::vector<GateRef> failBBGates;
|
||||
@ -92,7 +93,7 @@ bool PostSchedule::VisitHeapAlloc(GateRef gate, ControlFlowGraph &cfg, size_t bb
|
||||
ScheduleCurrentBB(currentBBGates, cfg, bbIdx, instIdx);
|
||||
return true;
|
||||
#endif
|
||||
} else if (flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE) {
|
||||
} else if (flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE || flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE) {
|
||||
LoweringHeapAllocate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag);
|
||||
ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx);
|
||||
return false;
|
||||
@ -312,14 +313,15 @@ void PostSchedule::LoweringHeapAllocate(GateRef gate,
|
||||
GateRef taggedIntMask = circuit_->GetConstantGateWithoutCache(
|
||||
MachineType::I64, JSTaggedValue::TAG_INT, GateType::NJSValue());
|
||||
GateRef taggedSize = builder_.Int64Or(size, taggedIntMask);
|
||||
GateRef target;
|
||||
if (flag == RegionSpaceFlag::IN_YOUNG_SPACE) {
|
||||
target = circuit_->GetConstantGateWithoutCache(
|
||||
MachineType::ARCH, RTSTUB_ID(AllocateInYoung), GateType::NJSValue());
|
||||
auto id = RTSTUB_ID(AllocateInYoung);
|
||||
if (flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE) {
|
||||
id = RTSTUB_ID(AllocateInSOld);
|
||||
} else if (flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE) {
|
||||
id = RTSTUB_ID(AllocateInSNonMovable);
|
||||
} else {
|
||||
target = circuit_->GetConstantGateWithoutCache(
|
||||
MachineType::ARCH, RTSTUB_ID(AllocateInSOld), GateType::NJSValue());
|
||||
ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE);
|
||||
}
|
||||
GateRef target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, id, GateType::NJSValue());
|
||||
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime));
|
||||
ASSERT(cs->IsRuntimeStub());
|
||||
GateRef reseverdFrameArgs = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue());
|
||||
|
@ -256,6 +256,15 @@ GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
|
||||
case OpCode::SET_ENTRIES:
|
||||
LowerToCommonStub(gate, CommonStubCSigns::JSSetEntries);
|
||||
break;
|
||||
case OpCode::BIGINT_CONSTRUCTOR:
|
||||
LowerBigIntConstructor(gate);
|
||||
break;
|
||||
case OpCode::BIGINT_CONSTRUCTOR_INT32:
|
||||
LowerBigIntConstructorInt32<true>(gate);
|
||||
break;
|
||||
case OpCode::BIGINT_CONSTRUCTOR_UINT32:
|
||||
LowerBigIntConstructorInt32<false>(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1790,7 +1799,6 @@ void TypedNativeInlineLowering::LowerToCommonStub(GateRef gate, CommonStubCSigns
|
||||
acc_.ReplaceGate(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
|
||||
void TypedNativeInlineLowering::LowerToBuiltinStub(GateRef gate, BuiltinsStubCSigns::ID id)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
@ -1831,4 +1839,45 @@ void TypedNativeInlineLowering::LowerGeneralWithoutArgs(GateRef gate, RuntimeStu
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void TypedNativeInlineLowering::LowerBigIntConstructor(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
Label hasException(&builder_);
|
||||
Label exit(&builder_);
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
auto result = builder_.CallRuntime(glue, RTSTUB_ID(BigIntConstructor), Gate::InvalidGateRef, {value}, gate);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
template <bool IS_SIGNED>
|
||||
void TypedNativeInlineLowering::LowerBigIntConstructorInt32(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
size_t length = 1;
|
||||
size_t size = AlignUp(BigInt::ComputeSize(length), static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
|
||||
GateRef sizeGate = builder_.IntPtr(size);
|
||||
GateRef hclass = builder_.GetGlobalConstantValue(ConstantIndex::BIGINT_CLASS_INDEX);
|
||||
GateRef sign = builder_.Int32(0);
|
||||
if constexpr (IS_SIGNED) {
|
||||
sign = builder_.Int32LSR(value, builder_.Int32(JSTaggedValue::INT_SIGN_BIT_OFFSET));
|
||||
auto temp = builder_.Int32ASR(value, builder_.Int32(JSTaggedValue::INT_SIGN_BIT_OFFSET));
|
||||
value = builder_.Int32Sub(builder_.Int32Xor(value, temp), temp);
|
||||
}
|
||||
|
||||
// looks like code from StartAllocate to FinishAllocate must be linear
|
||||
builder_.StartAllocate();
|
||||
GateRef object = builder_.HeapAlloc(acc_.GetGlueFromArgList(), sizeGate, GateType::TaggedValue(),
|
||||
RegionSpaceFlag::IN_SHARED_NON_MOVABLE);
|
||||
// initialization
|
||||
builder_.StoreConstOffset(VariableType::JS_POINTER(), object, JSObject::HCLASS_OFFSET, hclass,
|
||||
MemoryOrder::NeedBarrierAndAtomic());
|
||||
builder_.StoreConstOffset(VariableType::INT32(), object, BigInt::LENGTH_OFFSET, builder_.Int32(length));
|
||||
builder_.StoreConstOffset(VariableType::INT32(), object, BigInt::BIT_FIELD_OFFSET, sign);
|
||||
builder_.StoreConstOffset(VariableType::INT32(), object, BigInt::DATA_OFFSET, value);
|
||||
GateRef ret = builder_.FinishAllocate(object);
|
||||
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ private:
|
||||
void LowerNumberIsNaN(GateRef gate);
|
||||
void LowerNumberIsSafeInteger(GateRef gate);
|
||||
void LowerDateGetTime(GateRef gate);
|
||||
void LowerBigIntConstructor(GateRef gate);
|
||||
template <bool IS_SIGNED>
|
||||
void LowerBigIntConstructorInt32(GateRef gate);
|
||||
GateRef BuiltinIdToSize(GateRef ID);
|
||||
GateRef GetValueFromBuffer(GateRef bufferIndex, GateRef dataPointer, GateRef isLittleEndian, GateRef builtinId);
|
||||
GateRef SetValueInBuffer(GateRef bufferIndex,
|
||||
|
@ -536,6 +536,19 @@ TaggedObject *SharedHeap::AllocateNonMovableOrHugeObject(JSThread *thread, JSHCl
|
||||
return object;
|
||||
}
|
||||
|
||||
TaggedObject *SharedHeap::AllocateNonMovableOrHugeObject(JSThread *thread, size_t size)
|
||||
{
|
||||
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
|
||||
if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) {
|
||||
return AllocateHugeObject(thread, size);
|
||||
}
|
||||
auto object = reinterpret_cast<TaggedObject *>(sNonMovableSpace_->Allocate(thread, size));
|
||||
CHECK_SOBJ_AND_THROW_OOM_ERROR(thread, object, size, sNonMovableSpace_,
|
||||
"SharedHeap::AllocateNonMovableOrHugeObject");
|
||||
OnAllocateEvent(thread->GetEcmaVM(), object, size);
|
||||
return object;
|
||||
}
|
||||
|
||||
TaggedObject *SharedHeap::AllocateOldOrHugeObject(JSThread *thread, JSHClass *hclass)
|
||||
{
|
||||
size_t size = hclass->GetObjectSize();
|
||||
|
@ -531,6 +531,8 @@ public:
|
||||
|
||||
inline TaggedObject *AllocateNonMovableOrHugeObject(JSThread *thread, JSHClass *hclass, size_t size);
|
||||
|
||||
inline TaggedObject *AllocateNonMovableOrHugeObject(JSThread *thread, size_t size);
|
||||
|
||||
inline TaggedObject *AllocateOldOrHugeObject(JSThread *thread, JSHClass *hclass);
|
||||
|
||||
inline TaggedObject *AllocateOldOrHugeObject(JSThread *thread, JSHClass *hclass, size_t size);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "ecmascript/js_stable_array.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/base/typed_array_helper.h"
|
||||
#include "ecmascript/builtins/builtins_bigint.h"
|
||||
#include "ecmascript/builtins/builtins_iterator.h"
|
||||
#include "ecmascript/builtins/builtins_string_iterator.h"
|
||||
#include "ecmascript/compiler/builtins/containers_stub_builder.h"
|
||||
@ -166,21 +167,28 @@ DEF_RUNTIME_STUBS(AllocateInYoung)
|
||||
return JSTaggedValue(result).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(AllocateInSOld)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(AllocateInSOld);
|
||||
JSTaggedValue allocateSize = GetArg(argv, argc, 0); // 0: means the zeroth parameter
|
||||
auto size = static_cast<size_t>(allocateSize.GetInt());
|
||||
auto sharedHeap = const_cast<SharedHeap*>(SharedHeap::GetInstance());
|
||||
auto result = sharedHeap->AllocateOldOrHugeObject(thread, size);
|
||||
ASSERT(result != nullptr);
|
||||
if (argc > 1) { // 1: means the first parameter
|
||||
JSHandle<JSHClass> hclassHandle = GetHArg<JSHClass>(argv, argc, 1); // 1: means the first parameter
|
||||
auto hclass = JSHClass::Cast(hclassHandle.GetTaggedValue().GetTaggedObject());
|
||||
sharedHeap->SetHClassAndDoAllocateEvent(thread, result, hclass, size);
|
||||
#define ALLOCATE_IN_SHARED_HEAP(SPACE) \
|
||||
DEF_RUNTIME_STUBS(AllocateInS##SPACE) \
|
||||
{ \
|
||||
RUNTIME_STUBS_HEADER(AllocateInS##SPACE); \
|
||||
JSTaggedValue allocateSize = GetArg(argv, argc, 0); \
|
||||
auto size = static_cast<size_t>(allocateSize.GetInt()); \
|
||||
auto sharedHeap = const_cast<SharedHeap*>(SharedHeap::GetInstance()); \
|
||||
ASSERT(size <= MAX_REGULAR_HEAP_OBJECT_SIZE); \
|
||||
auto result = sharedHeap->Allocate##SPACE##OrHugeObject(thread, size); \
|
||||
ASSERT(result != nullptr); \
|
||||
if (argc > 1) { \
|
||||
JSHandle<JSHClass> hclassHandle = GetHArg<JSHClass>(argv, argc, 1); \
|
||||
auto hclass = JSHClass::Cast(hclassHandle.GetTaggedValue().GetTaggedObject()); \
|
||||
sharedHeap->SetHClassAndDoAllocateEvent(thread, result, hclass, size); \
|
||||
} \
|
||||
return JSTaggedValue(result).GetRawData(); \
|
||||
}
|
||||
return JSTaggedValue(result).GetRawData();
|
||||
}
|
||||
|
||||
ALLOCATE_IN_SHARED_HEAP(Old)
|
||||
ALLOCATE_IN_SHARED_HEAP(NonMovable)
|
||||
|
||||
#undef ALLOCATE_IN_SHARED_HEAP
|
||||
|
||||
DEF_RUNTIME_STUBS(TypedArraySpeciesCreate)
|
||||
{
|
||||
@ -970,6 +978,13 @@ DEF_RUNTIME_STUBS(DumpObject)
|
||||
return JSTaggedValue::True().GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(BigIntConstructor)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(BigIntConstructor);
|
||||
JSHandle<JSTaggedValue> value = GetHArg<JSTaggedValue>(argv, argc, 0);
|
||||
return builtins::BuiltinsBigInt::BigIntConstructorInternal(thread, value).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(CreateGeneratorObj)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(CreateGeneratorObj);
|
||||
|
@ -183,6 +183,7 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
|
||||
V(AddElementInternal) \
|
||||
V(AllocateInYoung) \
|
||||
V(AllocateInSOld) \
|
||||
V(AllocateInSNonMovable) \
|
||||
V(TypedArraySpeciesCreate) \
|
||||
V(CallInternalGetter) \
|
||||
V(CallInternalSetter) \
|
||||
@ -441,7 +442,8 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
|
||||
V(HasProperty) \
|
||||
V(DumpObject) \
|
||||
V(TryGetInternString) \
|
||||
V(TryToElementsIndexOrFindInStringTable)
|
||||
V(TryToElementsIndexOrFindInStringTable) \
|
||||
V(BigIntConstructor)
|
||||
|
||||
#define RUNTIME_STUB_LIST(V) \
|
||||
RUNTIME_ASM_STUB_LIST(V) \
|
||||
|
@ -16,6 +16,7 @@ group("ark_aot_builtin_inlining_bigint_test") {
|
||||
test_list = [
|
||||
"AsIntN",
|
||||
"AsUintN",
|
||||
"Constructor"
|
||||
]
|
||||
|
||||
deps = []
|
||||
|
17
test/aottest/builtin_inlining/bigint/Constructor/BUILD.gn
Normal file
17
test/aottest/builtin_inlining/bigint/Constructor/BUILD.gn
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_builtin_inlining_test_action("builtinBigIntConstructor") {
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return a * 2;
|
||||
}
|
||||
|
||||
function checkBigInt(x) {
|
||||
let val = BigInt(x);
|
||||
print(val);
|
||||
if (typeof val !== 'bigint') {
|
||||
print(typeof val);
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
function checkNotBigInt(x) {
|
||||
try {
|
||||
let val = BigInt(x);
|
||||
print(val);
|
||||
print(typeof val);
|
||||
} catch (e) {
|
||||
print(e.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
let n = BigInt(1);
|
||||
print(typeof n); //: bigint
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
n = BigInt(1)
|
||||
print(n); //: 1
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
n = BigInt(1, 2)
|
||||
print(typeof n); //: bigint
|
||||
print(n); //: 1
|
||||
//aot: [trace] aot inline function name: checkBigInt@builtinBigIntConstructor caller function name: func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(-1); //: -1
|
||||
//aot: [trace] aot inline function name: checkBigInt@builtinBigIntConstructor caller function name: func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(-12345); //: -12345
|
||||
//aot: [trace] aot inline function name: checkBigInt@builtinBigIntConstructor caller function name: func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(1n); //: 1
|
||||
//aot: [trace] aot inline function name: checkBigInt@builtinBigIntConstructor caller function name: func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(-1n); //: -1
|
||||
//aot: [trace] aot inline function name: checkBigInt@builtinBigIntConstructor caller function name: func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(0.0); //: 0
|
||||
//aot: [trace] aot inline function name: checkBigInt@builtinBigIntConstructor caller function name: func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(-0.0); //: 0
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(BigInt(-1)); //: -1
|
||||
|
||||
// test large ints
|
||||
// 2^31-1
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(2147483647); //: 2147483647
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(2147483647 << 1); //: -2
|
||||
//-(2^32)
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(-2147483648); //: -2147483648
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(Number.MIN_SAFE_INTEGER); //: -9007199254740991
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(Number.MAX_SAFE_INTEGER); //: 9007199254740991
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(Number.MAX_SAFE_INTEGER - 0.5); //: 9007199254740990
|
||||
// 1e22
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(10000000000000000000000) //: 10000000000000000000000
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(1e23) //: 99999999999999991611392
|
||||
// also 1e23
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(100000000000000000000000) //: 99999999999999991611392
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt("100000000000000000000000") //: 100000000000000000000000
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt("-100000000000000000000000") //: -100000000000000000000000
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(100000000000000000000000n) //: 100000000000000000000000
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt(BigInt(100000000000000000000000n)) //: 100000000000000000000000
|
||||
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt("0xf") //: 15
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt({ valueOf: () => 1 }); //: 1
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkBigInt@builtinBigIntConstructor
|
||||
checkBigInt({ valueOf: () => "-11" }); //: -11
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(1.5); //: RangeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(-20.000001); //: RangeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(Number.EPSILON); //: RangeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(Number.POSITIVE_INFINITY); //: RangeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(Number.NEGATIVE_INFINITY); //: RangeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(NaN); //: RangeError
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(null); //: TypeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt(undefined); //: TypeError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt("f"); //: SyntaxError
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:checkNotBigInt@builtinBigIntConstructor
|
||||
checkNotBigInt({}); //: SyntaxError
|
||||
|
||||
try {
|
||||
//NOTE: not inlined by now
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
n = BigInt();
|
||||
} catch(e) {
|
||||
print(e.name); //: TypeError
|
||||
}
|
||||
|
||||
try {
|
||||
// not inlined as expected
|
||||
n = new BigInt(1);
|
||||
} catch(e) {
|
||||
print(e.name); //: TypeError
|
||||
}
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
n = 2n.constructor(12);
|
||||
print(typeof n); //: bigint
|
||||
print(n); //: 12
|
||||
|
||||
//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinBigIntConstructor
|
||||
n = globalThis.BigInt(12);
|
||||
print(typeof n); //: bigint
|
||||
print(n); //: 12
|
||||
|
||||
if (ArkTools.isAOTCompiled(checkBigInt)) {
|
||||
BigInt = replace;
|
||||
}
|
||||
//aot: [trace] Check Type: NotCallTarget1
|
||||
print(BigInt(2)); //pgo: 2
|
||||
//aot: 4
|
Loading…
Reference in New Issue
Block a user