mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
!526 Add Container ArrayList
Merge pull request !526 from 刘甘霖/container_arraylist
This commit is contained in:
commit
74d4f0e409
3
BUILD.gn
3
BUILD.gn
@ -344,7 +344,8 @@ ecma_source = [
|
||||
"ecmascript/js_array.cpp",
|
||||
"ecmascript/js_array_iterator.cpp",
|
||||
"ecmascript/js_arraybuffer.cpp",
|
||||
"ecmascript/js_arraylist.cpp",
|
||||
"ecmascript/js_api_arraylist.cpp",
|
||||
"ecmascript/js_api_arraylist_iterator.cpp",
|
||||
"ecmascript/js_async_function.cpp",
|
||||
"ecmascript/js_dataview.cpp",
|
||||
"ecmascript/js_date.cpp",
|
||||
|
@ -58,7 +58,7 @@
|
||||
#include "ecmascript/ecma_runtime_call_info.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
#include "ecmascript/js_collator.h"
|
||||
|
@ -26,7 +26,6 @@ namespace panda::ecmascript::kungfu {
|
||||
V(CallGetter2, 4) \
|
||||
V(CallInternalGetter, 3) \
|
||||
V(ThrowTypeError, 2) \
|
||||
V(JSArrayListSetByIndex, 4) \
|
||||
V(JSProxySetProperty, 6) \
|
||||
V(GetHash32, 2) \
|
||||
V(FindElementWithCache, 4) \
|
||||
|
@ -1438,9 +1438,11 @@ GateRef Stub::IsSpecialIndexedObj(GateRef jsType)
|
||||
|
||||
GateRef Stub::IsSpecialContainer(GateRef jsType)
|
||||
{
|
||||
// arraylist and vector has fast pass now
|
||||
return TruncInt32ToInt1(Int32And(
|
||||
ZExtInt1ToInt32(Int32GreaterThanOrEqual(jsType, GetInt32Constant(static_cast<int32_t>(JSType::JS_ARRAY_LIST)))),
|
||||
ZExtInt1ToInt32(Int32LessThanOrEqual(jsType, GetInt32Constant(static_cast<int32_t>(JSType::JS_QUEUE))))));
|
||||
ZExtInt1ToInt32(
|
||||
Int32GreaterThanOrEqual(jsType, GetInt32Constant(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST)))),
|
||||
ZExtInt1ToInt32(Int32LessThanOrEqual(jsType, GetInt32Constant(static_cast<int32_t>(JSType::JS_API_VECTOR))))));
|
||||
}
|
||||
|
||||
GateRef Stub::IsAccessorInternal(GateRef value)
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "ecmascript/compiler/stub.h"
|
||||
#include "ecmascript/compiler/llvm_ir_builder.h"
|
||||
#include "ecmascript/compiler/stub-inl.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_object.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
#include "ecmascript/tagged_hash_table-inl.h"
|
||||
@ -2375,20 +2375,8 @@ GateRef Stub::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index,
|
||||
Branch(IsSpecialIndexedObj(jsType), &isSpecialIndex, ¬SpecialIndex);
|
||||
Bind(&isSpecialIndex);
|
||||
{
|
||||
Label isSpecialContainer(env);
|
||||
Label notSpecialContainer(env);
|
||||
// Add SpecialContainer
|
||||
Branch(IsSpecialContainer(jsType), &isSpecialContainer, ¬SpecialContainer);
|
||||
Bind(&isSpecialContainer);
|
||||
{
|
||||
returnValue = SetContainerProperty(glue, *holder, index, value, jsType);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬SpecialContainer);
|
||||
{
|
||||
returnValue = GetHoleConstant(StubMachineType::UINT64);
|
||||
Jump(&exit);
|
||||
}
|
||||
returnValue = GetHoleConstant(StubMachineType::UINT64);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬SpecialIndex);
|
||||
{
|
||||
@ -2986,7 +2974,7 @@ GateRef Stub::GetContainerProperty(GateRef glue, GateRef receiver, GateRef index
|
||||
queueLabel,
|
||||
};
|
||||
std::array<int64_t, 2> keyValues = { // 2 : 2 means that there are 2 args in total.
|
||||
static_cast<int64_t>(JSType::JS_ARRAY_LIST),
|
||||
static_cast<int64_t>(JSType::JS_API_ARRAY_LIST),
|
||||
static_cast<int64_t>(JSType::JS_QUEUE),
|
||||
};
|
||||
// 2 : 2 means that there are 2 cases.
|
||||
@ -3019,7 +3007,7 @@ GateRef Stub::JSArrayListGet(GateRef glue, GateRef receiver, GateRef index)
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, StubMachineType::TAGGED, GetUndefinedConstant());
|
||||
|
||||
GateRef lengthOffset = GetIntPtrConstant(panda::ecmascript::JSArrayList::LENGTH_OFFSET);
|
||||
GateRef lengthOffset = GetIntPtrConstant(panda::ecmascript::JSAPIArrayList::LENGTH_OFFSET);
|
||||
GateRef length = TaggedCastToInt32(Load(StubMachineType::UINT64, receiver, lengthOffset));
|
||||
Label isVailedIndex(env);
|
||||
Label notValidIndex(env);
|
||||
@ -3045,46 +3033,4 @@ GateRef Stub::JSArrayListGet(GateRef glue, GateRef receiver, GateRef index)
|
||||
env->PopCurrentLabel();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef Stub::SetContainerProperty(GateRef glue, GateRef receiver, GateRef index, GateRef value, GateRef jsType)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->PushCurrentLabel(&entry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, StubMachineType::UINT64, GetUndefinedConstant(StubMachineType::UINT64));
|
||||
Label arrayListLabel(env);
|
||||
Label queueLabel(env);
|
||||
Label defaultLabel(env);
|
||||
std::array<Label, 2> repCaseLabels = { // 2 : 2 means that there are 2 args in total.
|
||||
arrayListLabel,
|
||||
queueLabel,
|
||||
};
|
||||
std::array<int64_t, 2> keyValues = { // 2 : 2 means that there are 2 args in total.
|
||||
static_cast<int64_t>(JSType::JS_ARRAY_LIST),
|
||||
static_cast<int64_t>(JSType::JS_QUEUE),
|
||||
};
|
||||
// 2 : 2 means that there are 2 cases.
|
||||
Switch(ZExtInt32ToInt64(jsType), &defaultLabel, keyValues.data(), repCaseLabels.data(), 2);
|
||||
Bind(&arrayListLabel);
|
||||
{
|
||||
StubDescriptor *jsarraylistSetByIndex = GET_STUBDESCRIPTOR(JSArrayListSetByIndex);
|
||||
CallRuntime(jsarraylistSetByIndex, glue, GetInt64Constant(FAST_STUB_ID(JSArrayListSetByIndex)),
|
||||
{ glue, receiver, index, value });
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&queueLabel);
|
||||
{
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&defaultLabel);
|
||||
{
|
||||
Jump(&exit);
|
||||
}
|
||||
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->PopCurrentLabel();
|
||||
return ret;
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -747,7 +747,6 @@ public:
|
||||
|
||||
// Add SpecialContainer
|
||||
GateRef GetContainerProperty(GateRef glue, GateRef receiver, GateRef index, GateRef jsType);
|
||||
GateRef SetContainerProperty(GateRef glue, GateRef receiver, GateRef index, GateRef value, GateRef jsType);
|
||||
GateRef JSArrayListGet(GateRef glue, GateRef receiver, GateRef index);
|
||||
|
||||
private:
|
||||
|
@ -979,23 +979,6 @@ CALL_STUB_INIT_DESCRIPTOR(ThrowIfNotObject)
|
||||
descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB);
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(JSArrayListSetByIndex)
|
||||
{
|
||||
// 4 : 4 input parameters
|
||||
StubDescriptor arraylistSetByIndex("JSArrayListSetByIndex", 0, 4, ArgumentsOrder::DEFAULT_ORDER,
|
||||
StubMachineType::NONE);
|
||||
*descriptor = arraylistSetByIndex;
|
||||
// 4 : 4 input parameters
|
||||
std::array<StubMachineType, 4> params = {
|
||||
StubMachineType::NATIVE_POINTER,
|
||||
StubMachineType::TAGGED_POINTER,
|
||||
StubMachineType::INT32,
|
||||
StubMachineType::TAGGED,
|
||||
};
|
||||
descriptor->SetParameters(params.data());
|
||||
descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB);
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(InsertOldToNewRememberedSet)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
|
@ -14,10 +14,17 @@
|
||||
*/
|
||||
|
||||
#include "containers_arraylist.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/base/array_helper.h"
|
||||
#include "ecmascript/base/number_helper.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/tagged_array-inl.h"
|
||||
#include "ecmascript/internal_call_params.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_iterator.h"
|
||||
|
||||
namespace panda::ecmascript::containers {
|
||||
JSTaggedValue ContainersArrayList::ArrayListConstructor(EcmaRuntimeCallInfo *argv)
|
||||
@ -33,7 +40,7 @@ JSTaggedValue ContainersArrayList::ArrayListConstructor(EcmaRuntimeCallInfo *arg
|
||||
}
|
||||
JSHandle<JSTaggedValue> constructor = GetConstructor(argv);
|
||||
JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget);
|
||||
|
||||
obj->SetElements(thread, factory->NewTaggedArray(JSAPIArrayList::DEFAULT_CAPACITY_LENGTH));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
return obj.GetTaggedValue();
|
||||
@ -47,23 +54,457 @@ JSTaggedValue ContainersArrayList::Add(EcmaRuntimeCallInfo *argv)
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSArrayList", JSTaggedValue::Exception());
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
|
||||
JSArrayList::Add(thread, JSHandle<JSArrayList>::Cast(self), value);
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
return GetTaggedBoolean(JSAPIArrayList::Add(thread, JSHandle<JSAPIArrayList>::Cast(self), value));
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Insert(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Insert);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
JSHandle<JSTaggedValue> index = GetCallArg(argv, 1);
|
||||
JSAPIArrayList::Insert(thread, JSHandle<JSAPIArrayList>::Cast(self), value, JSTaggedValue::ToUint32(thread, index));
|
||||
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Clear(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Clear);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSAPIArrayList::Clear(thread, JSHandle<JSAPIArrayList>::Cast(self));
|
||||
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Iterator(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue ContainersArrayList::Clone(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Iterator);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Clone);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSAPIArrayList> newArrayList = JSAPIArrayList::Clone(thread, JSHandle<JSAPIArrayList>::Cast(self));
|
||||
|
||||
return newArrayList.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Has(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Has);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
bool isHas = JSHandle<JSAPIArrayList>::Cast(self)->Has(value.GetTaggedValue());
|
||||
|
||||
return GetTaggedBoolean(isHas);
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::GetCapacity(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetCapacity);
|
||||
JSThread *thread = argv->GetThread();
|
||||
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
uint32_t capacity = JSAPIArrayList::GetCapacity(thread, JSHandle<JSAPIArrayList>::Cast(self));
|
||||
|
||||
return JSTaggedValue(capacity);
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::IncreaseCapacityTo(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, IncreaseCapacityTo);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> newCapacity = GetCallArg(argv, 0);
|
||||
JSAPIArrayList::IncreaseCapacityTo(thread, JSHandle<JSAPIArrayList>::Cast(self),
|
||||
JSTaggedValue::ToUint32(thread, newCapacity));
|
||||
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::TrimToCurrentLength(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, TrimToCurrentLength);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSAPIArrayList::TrimToCurrentLength(thread, JSHandle<JSAPIArrayList>::Cast(self));
|
||||
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Get(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Get);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
|
||||
JSTaggedValue element = JSHandle<JSAPIArrayList>::Cast(self)->Get(thread, JSTaggedValue::ToUint32(thread, value));
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::GetIndexOf(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetIndexOf);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
|
||||
return JSTaggedValue(JSAPIArrayList::GetIndexOf(thread, JSHandle<JSAPIArrayList>::Cast(self), value));
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::IsEmpty(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, IsEmpty);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
return JSTaggedValue(JSAPIArrayList::IsEmpty(JSHandle<JSAPIArrayList>::Cast(self)));
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::GetLastIndexOf(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetLastIndexOf);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
|
||||
return JSTaggedValue(JSAPIArrayList::GetLastIndexOf(thread, JSHandle<JSAPIArrayList>::Cast(self), value));
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::RemoveByIndex(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, RemoveByIndex);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
JSAPIArrayList::RemoveByIndex(thread, JSHandle<JSAPIArrayList>::Cast(self), JSTaggedValue::ToUint32(thread, value));
|
||||
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Remove(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Remove);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
|
||||
bool isRemove = JSAPIArrayList::Remove(thread, JSHandle<JSAPIArrayList>::Cast(self), value);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
return GetTaggedBoolean(isRemove);
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::RemoveByRange(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, RemoveByRange);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> startIndex = GetCallArg(argv, 0);
|
||||
JSHandle<JSTaggedValue> endIndex = GetCallArg(argv, 1);
|
||||
JSAPIArrayList::RemoveByRange(thread, JSHandle<JSAPIArrayList>::Cast(self), startIndex, endIndex);
|
||||
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::ReplaceAllElements(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, ReplaceAllElements);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
|
||||
if (!callbackFnHandle->IsCallable()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
|
||||
}
|
||||
JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
|
||||
|
||||
return JSAPIArrayList::ReplaceAllElements(thread, self, callbackFnHandle, thisArgHandle);
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Set(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Set);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> index = GetCallArg(argv, 0);
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 1);
|
||||
JSHandle<JSAPIArrayList>::Cast(self)->Set(thread, JSTaggedValue::ToUint32(thread, index), value.GetTaggedValue());
|
||||
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::SubArrayList(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, SubArrayList);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> value1 = GetCallArg(argv, 0);
|
||||
JSHandle<JSTaggedValue> value2 = GetCallArg(argv, 1);
|
||||
JSHandle<JSAPIArrayList> newArrayList =
|
||||
JSAPIArrayList::SubArrayList(thread, JSHandle<JSAPIArrayList>::Cast(self), value1, value2);
|
||||
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return newArrayList.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::Sort(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Array, Sort);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
|
||||
if (callbackFnHandle->IsUndefined() || !callbackFnHandle->IsCallable()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Callable is false", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> elements(thread, JSHandle<JSAPIArrayList>::Cast(self)->GetElements());
|
||||
JSMutableHandle<JSTaggedValue> presentValue(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> middleValue(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> previousValue(thread, JSTaggedValue::Undefined());
|
||||
uint32_t length = JSHandle<JSAPIArrayList>::Cast(self)->GetLength().GetArrayLength();
|
||||
|
||||
for (uint32_t i = 1; i < length; i++) {
|
||||
uint32_t beginIndex = 0;
|
||||
uint32_t endIndex = i;
|
||||
presentValue.Update(elements->Get(i));
|
||||
while (beginIndex < endIndex) {
|
||||
uint32_t middleIndex = (beginIndex + endIndex) / 2; // 2 : half
|
||||
middleValue.Update(elements->Get(middleIndex));
|
||||
int32_t compareResult = base::ArrayHelper::SortCompare(thread, callbackFnHandle,
|
||||
middleValue, presentValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (compareResult > 0) {
|
||||
endIndex = middleIndex;
|
||||
} else {
|
||||
beginIndex = middleIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (endIndex >= 0 && endIndex < i) {
|
||||
for (uint32_t j = i; j > endIndex; j--) {
|
||||
previousValue.Update(elements->Get(j - 1));
|
||||
elements->Set(thread, j, previousValue.GetTaggedValue());
|
||||
}
|
||||
elements->Set(thread, endIndex, presentValue.GetTaggedValue());
|
||||
}
|
||||
}
|
||||
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::GetSize(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetSize);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
return JSTaggedValue(JSHandle<JSAPIArrayList>::Cast(self)->GetSize());
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::ConvertToArray(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, ConvertToArray);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(self);
|
||||
uint32_t length = arrayList->GetLength().GetArrayLength();
|
||||
JSHandle<JSArray> array = thread->GetEcmaVM()->GetFactory()->NewJSArray();
|
||||
array->SetArrayLength(thread, length);
|
||||
JSHandle<TaggedArray> arrayListElements(thread, arrayList->GetElements());
|
||||
|
||||
uint32_t arrayListCapacity = arrayListElements->GetLength();
|
||||
|
||||
JSHandle<TaggedArray> newElements =
|
||||
thread->GetEcmaVM()->GetFactory()->CopyArray(arrayListElements, arrayListCapacity, arrayListCapacity);
|
||||
array->SetElements(thread, newElements);
|
||||
return array.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::ForEach(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, ForEach);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
|
||||
if (!callbackFnHandle->IsCallable()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
|
||||
|
||||
return JSAPIArrayList::ForEach(thread, self, callbackFnHandle, thisArgHandle);
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersArrayList::GetIteratorObj(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetIteratorObj);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> self = GetThis(argv);
|
||||
|
||||
if (!self->IsJSAPIArrayList()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSAPIArrayList", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSTaggedValue values = JSAPIArrayList::GetIteratorObj(thread, JSHandle<JSAPIArrayList>::Cast(self));
|
||||
|
||||
return values;
|
||||
}
|
||||
} // namespace panda::ecmascript::containers
|
||||
|
@ -28,7 +28,28 @@ public:
|
||||
static JSTaggedValue ArrayListConstructor(EcmaRuntimeCallInfo *argv);
|
||||
|
||||
static JSTaggedValue Add(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Iterator(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Insert(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Clear(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Clone(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Has(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue GetCapacity(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue IncreaseCapacityTo(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue TrimToCurrentLength(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue GetIndexOf(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue IsEmpty(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue GetLastIndexOf(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue RemoveByIndex(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Remove(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue RemoveByRange(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue ReplaceAllElements(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Sort(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue SubArrayList(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue ConvertToArray(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue ForEach(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue GetIteratorObj(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Get(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Set(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue GetSize(EcmaRuntimeCallInfo *argv);
|
||||
};
|
||||
} // namespace panda::ecmascript::containers
|
||||
#endif // ECMASCRIPT_CONTAINERS_CONTAINERS_ARRAYLIST_H
|
||||
|
@ -19,12 +19,14 @@
|
||||
#include "containers_treemap.h"
|
||||
#include "containers_treeset.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/global_env_constants.h"
|
||||
#include "ecmascript/interpreter/fast_runtime_stub-inl.h"
|
||||
#include "ecmascript/js_api_tree_map.h"
|
||||
#include "ecmascript/js_api_tree_map_iterator.h"
|
||||
#include "ecmascript/js_api_tree_set.h"
|
||||
#include "ecmascript/js_api_tree_set_iterator.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
|
||||
namespace panda::ecmascript::containers {
|
||||
@ -185,29 +187,78 @@ void ContainersPrivate::SetStringTagSymbol(JSThread *thread, const JSHandle<Glob
|
||||
|
||||
JSHandle<JSTaggedValue> ContainersPrivate::InitializeArrayList(JSThread *thread)
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
// ArrayList.prototype
|
||||
JSHandle<JSObject> arrayListFuncPrototype = factory->NewEmptyJSObject();
|
||||
JSHandle<JSTaggedValue> arrayListFuncPrototypeValue(arrayListFuncPrototype);
|
||||
JSHandle<JSObject> prototype = factory->NewEmptyJSObject();
|
||||
JSHandle<JSTaggedValue> arrayListFuncPrototypeValue(prototype);
|
||||
// ArrayList.prototype_or_dynclass
|
||||
JSHandle<JSHClass> arrayListInstanceDynclass =
|
||||
factory->NewEcmaDynClass(JSArrayList::SIZE, JSType::JS_ARRAY_LIST, arrayListFuncPrototypeValue);
|
||||
factory->NewEcmaDynClass(JSAPIArrayList::SIZE, JSType::JS_API_ARRAY_LIST, arrayListFuncPrototypeValue);
|
||||
// ArrayList() = new Function()
|
||||
JSHandle<JSTaggedValue> arrayListFunction(NewContainerConstructor(
|
||||
thread, arrayListFuncPrototype, ContainersArrayList::ArrayListConstructor, "ArrayList", FuncLength::ZERO));
|
||||
thread, prototype, ContainersArrayList::ArrayListConstructor, "ArrayList", FuncLength::ZERO));
|
||||
JSHandle<JSFunction>(arrayListFunction)->SetFunctionPrototype(thread, arrayListInstanceDynclass.GetTaggedValue());
|
||||
|
||||
// "constructor" property on the prototype
|
||||
JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
|
||||
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(arrayListFuncPrototype), constructorKey, arrayListFunction);
|
||||
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(prototype), constructorKey, arrayListFunction);
|
||||
|
||||
// ArrayList.prototype.add()
|
||||
SetFrozenFunction(thread, arrayListFuncPrototype, "add", ContainersArrayList::Add, FuncLength::ONE);
|
||||
// ArrayList.prototype
|
||||
SetFrozenFunction(thread, prototype, "add", ContainersArrayList::Add, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "insert", ContainersArrayList::Insert, FuncLength::TWO);
|
||||
SetFrozenFunction(thread, prototype, "clear", ContainersArrayList::Clear, FuncLength::ZERO);
|
||||
SetFrozenFunction(thread, prototype, "clone", ContainersArrayList::Clone, FuncLength::ZERO);
|
||||
SetFrozenFunction(thread, prototype, "has", ContainersArrayList::Has, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "getCapacity", ContainersArrayList::GetCapacity, FuncLength::ZERO);
|
||||
SetFrozenFunction(thread, prototype, "increaseCapacityTo",
|
||||
ContainersArrayList::IncreaseCapacityTo, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "trimToCurrentLength",
|
||||
ContainersArrayList::TrimToCurrentLength, FuncLength::ZERO);
|
||||
SetFrozenFunction(thread, prototype, "getIndexOf", ContainersArrayList::GetIndexOf, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "isEmpty", ContainersArrayList::IsEmpty, FuncLength::ZERO);
|
||||
SetFrozenFunction(thread, prototype, "getLastIndexOf", ContainersArrayList::GetLastIndexOf, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "removeByIndex", ContainersArrayList::RemoveByIndex, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "remove", ContainersArrayList::Remove, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "removeByRange", ContainersArrayList::RemoveByRange, FuncLength::TWO);
|
||||
SetFrozenFunction(thread, prototype, "replaceAllElements",
|
||||
ContainersArrayList::ReplaceAllElements, FuncLength::TWO);
|
||||
SetFrozenFunction(thread, prototype, "sort", ContainersArrayList::Sort, FuncLength::ONE);
|
||||
SetFrozenFunction(thread, prototype, "subArrayList", ContainersArrayList::SubArrayList, FuncLength::TWO);
|
||||
SetFrozenFunction(thread, prototype, "convertToArray", ContainersArrayList::ConvertToArray, FuncLength::ZERO);
|
||||
SetFrozenFunction(thread, prototype, "forEach", ContainersArrayList::ForEach, FuncLength::TWO);
|
||||
|
||||
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
|
||||
SetStringTagSymbol(thread, env, prototype, "ArrayList");
|
||||
|
||||
JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersArrayList::GetSize, "length",
|
||||
FuncLength::ZERO);
|
||||
JSHandle<JSTaggedValue> lengthKey(factory->NewFromCanBeCompressString("length"));
|
||||
SetGetter(thread, prototype, lengthKey, lengthGetter);
|
||||
|
||||
SetFunctionAtSymbol(thread, env, prototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
|
||||
ContainersArrayList::GetIteratorObj, FuncLength::ONE);
|
||||
ContainersPrivate::InitializeArrayListIterator(thread, env, globalConst);
|
||||
globalConst->SetConstant(ConstantIndex::ARRAYLIST_FUNCTION_INDEX, arrayListFunction.GetTaggedValue());
|
||||
return arrayListFunction;
|
||||
}
|
||||
|
||||
void ContainersPrivate::InitializeArrayListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
|
||||
GlobalEnvConstants *globalConst)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
// Iterator.dynclass
|
||||
JSHandle<JSHClass> iteratorFuncDynclass =
|
||||
factory->NewEcmaDynClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
|
||||
// ArrayListIterator.prototype
|
||||
JSHandle<JSObject> arrayListIteratorPrototype(factory->NewJSObject(iteratorFuncDynclass));
|
||||
// Iterator.prototype.next()
|
||||
SetFrozenFunction(thread, arrayListIteratorPrototype, "next", JSAPIArrayListIterator::Next, FuncLength::ONE);
|
||||
SetStringTagSymbol(thread, env, arrayListIteratorPrototype, "ArrayList Iterator");
|
||||
globalConst->SetConstant(ConstantIndex::ARRAYLIST_ITERATOR_PROTOTYPE_INDEX,
|
||||
arrayListIteratorPrototype.GetTaggedValue());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> ContainersPrivate::InitializeTreeMap(JSThread *thread)
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
|
@ -68,6 +68,8 @@ private:
|
||||
static JSTaggedValue InitializeContainer(JSThread *thread, const JSHandle<JSObject> &obj, InitializeFunction func,
|
||||
const char *name);
|
||||
static JSHandle<JSTaggedValue> InitializeArrayList(JSThread *thread);
|
||||
static void InitializeArrayListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
|
||||
GlobalEnvConstants *globalConst);
|
||||
static JSHandle<JSTaggedValue> InitializeTreeMap(JSThread *thread);
|
||||
static void InitializeTreeMapIterator(JSThread *thread);
|
||||
static JSHandle<JSTaggedValue> InitializeTreeSet(JSThread *thread);
|
||||
|
@ -38,7 +38,8 @@
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
#include "ecmascript/js_collator.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
@ -256,8 +257,10 @@ CString JSHClass::DumpJSType(JSType type)
|
||||
return "EcmaModule";
|
||||
case JSType::CLASS_INFO_EXTRACTOR:
|
||||
return "ClassInfoExtractor";
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
return "ArrayList";
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR:
|
||||
return "JSArraylistIterator";
|
||||
case JSType::JS_API_TREE_MAP:
|
||||
return "TreeMap";
|
||||
case JSType::JS_API_TREE_SET:
|
||||
@ -603,8 +606,11 @@ static void DumpObject(JSThread *thread, TaggedObject *obj, std::ostream &os)
|
||||
case JSType::CLASS_INFO_EXTRACTOR:
|
||||
ClassInfoExtractor::Cast(obj)->Dump(thread, os);
|
||||
break;
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
JSArrayList::Cast(obj)->Dump(thread, os);
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
JSAPIArrayList::Cast(obj)->Dump(thread, os);
|
||||
break;
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR:
|
||||
JSAPIArrayListIterator::Cast(obj)->Dump(thread, os);
|
||||
break;
|
||||
case JSType::JS_API_TREE_MAP:
|
||||
JSAPITreeMap::Cast(obj)->Dump(thread, os);
|
||||
@ -1309,12 +1315,20 @@ void JSArray::Dump(JSThread *thread, std::ostream &os) const
|
||||
JSObject::Dump(thread, os);
|
||||
}
|
||||
|
||||
void JSArrayList::Dump(JSThread *thread, std::ostream &os) const
|
||||
void JSAPIArrayList::Dump(JSThread *thread, std::ostream &os) const
|
||||
{
|
||||
os << " - length: " << std::dec << GetLength().GetArrayLength() << "\n";
|
||||
JSObject::Dump(thread, os);
|
||||
}
|
||||
|
||||
void JSAPIArrayListIterator::Dump(JSThread *thread, std::ostream &os) const
|
||||
{
|
||||
JSAPIArrayList *arrayList = JSAPIArrayList::Cast(GetIteratedArrayList().GetTaggedObject());
|
||||
os << " - length: " << std::dec << arrayList->GetLength().GetArrayLength() << "\n";
|
||||
os << " - nextIndex: " << std::dec << GetNextIndex().GetInt() << "\n";
|
||||
JSObject::Dump(thread, os);
|
||||
}
|
||||
|
||||
void JSArrayIterator::Dump(JSThread *thread, std::ostream &os) const
|
||||
{
|
||||
JSArray *array = JSArray::Cast(GetIteratedArray().GetTaggedObject());
|
||||
@ -2284,8 +2298,11 @@ static void DumpObject(JSThread *thread, TaggedObject *obj,
|
||||
case JSType::ECMA_MODULE:
|
||||
EcmaModule::Cast(obj)->DumpForSnapshot(thread, vec);
|
||||
return;
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
JSArrayList::Cast(obj)->DumpForSnapshot(thread, vec);
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
JSAPIArrayList::Cast(obj)->DumpForSnapshot(thread, vec);
|
||||
return;
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR:
|
||||
JSAPIArrayListIterator::Cast(obj)->DumpForSnapshot(thread, vec);
|
||||
return;
|
||||
case JSType::JS_API_TREE_MAP:
|
||||
JSAPITreeMap::Cast(obj)->DumpForSnapshot(thread, vec);
|
||||
@ -2677,12 +2694,21 @@ void JSArray::DumpForSnapshot([[maybe_unused]] JSThread *thread,
|
||||
JSObject::DumpForSnapshot(thread, vec);
|
||||
}
|
||||
|
||||
void JSArrayList::DumpForSnapshot([[maybe_unused]] JSThread *thread,
|
||||
std::vector<std::pair<CString, JSTaggedValue>> &vec) const
|
||||
void JSAPIArrayList::DumpForSnapshot([[maybe_unused]] JSThread *thread,
|
||||
std::vector<std::pair<CString, JSTaggedValue>> &vec) const
|
||||
{
|
||||
JSObject::DumpForSnapshot(thread, vec);
|
||||
}
|
||||
|
||||
void JSAPIArrayListIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread,
|
||||
std::vector<std::pair<CString, JSTaggedValue>> &vec) const
|
||||
{
|
||||
JSAPIArrayList *arraylist = JSAPIArrayList::Cast(GetIteratedArrayList().GetTaggedObject());
|
||||
arraylist->DumpForSnapshot(thread, vec);
|
||||
vec.push_back(std::make_pair(CString("NextIndex"), GetNextIndex()));
|
||||
JSObject::DumpForSnapshot(thread, vec);
|
||||
}
|
||||
|
||||
void JSArrayIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread,
|
||||
std::vector<std::pair<CString, JSTaggedValue>> &vec) const
|
||||
{
|
||||
@ -2862,6 +2888,8 @@ void GlobalEnv::DumpForSnapshot([[maybe_unused]] JSThread *thread,
|
||||
vec.push_back(std::make_pair(CString("AsyncFunctionString"), globalConst->GetAsyncFunctionString()));
|
||||
vec.push_back(std::make_pair(CString("ThrowerString"), globalConst->GetThrowerString()));
|
||||
vec.push_back(std::make_pair(CString("Undefined"), globalConst->GetUndefined()));
|
||||
vec.push_back(std::make_pair(CString("ArrayListFunction"), globalConst->GetArrayListFunction()));
|
||||
vec.push_back(std::make_pair(CString("ArrayListIteratorPrototype"), globalConst->GetArrayListIteratorPrototype()));
|
||||
vec.push_back(std::make_pair(CString("TreeMapIteratorPrototype"), globalConst->GetTreeMapIteratorPrototype()));
|
||||
vec.push_back(std::make_pair(CString("TreeSetIteratorPrototype"), globalConst->GetTreeSetIteratorPrototype()));
|
||||
}
|
||||
|
@ -86,6 +86,8 @@ class JSThread;
|
||||
V(JSTaggedValue, EnumerableString, ENUMERABLE_STRING_INDEX, enumerable) \
|
||||
V(JSTaggedValue, ConfigurableString, CONFIGURABLE_STRING_INDEX, configurable) \
|
||||
/* non ECMA standard jsapi containers iterators */ \
|
||||
V(JSTaggedValue, ArrayListFunction, ARRAYLIST_FUNCTION_INDEX, ArrayListFunction) \
|
||||
V(JSTaggedValue, ArrayListIteratorPrototype, ARRAYLIST_ITERATOR_PROTOTYPE_INDEX, ArrayListIterator) \
|
||||
V(JSTaggedValue, TreeMapIteratorPrototype, TREEMAP_ITERATOR_PROTOTYPE_INDEX, TreeMapIterator) \
|
||||
V(JSTaggedValue, TreeSetIteratorPrototype, TREESET_ITERATOR_PROTOTYPE_INDEX, TreeSetIterator) \
|
||||
/* SymbolTable*RegisterSymbols */ \
|
||||
|
@ -323,8 +323,10 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry)
|
||||
return GetString("CompletionRecord");
|
||||
case JSType::ECMA_MODULE:
|
||||
return GetString("EcmaModule");
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
return GetString("ArrayList");
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR:
|
||||
return GetString("ArrayListIterator");
|
||||
case JSType::JS_API_TREE_MAP:
|
||||
return GetString("TreeMap");
|
||||
case JSType::JS_API_TREE_SET:
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "ecmascript/global_dictionary-inl.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/internal_call_params.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_hclass-inl.h"
|
||||
#include "ecmascript/js_proxy.h"
|
||||
@ -163,7 +163,7 @@ bool FastRuntimeStub::IsSpecialReceiverObj(JSType jsType)
|
||||
|
||||
bool FastRuntimeStub::IsSpecialContainer(JSType jsType)
|
||||
{
|
||||
return jsType >= JSType::JS_ARRAY_LIST && jsType <= JSType::JS_QUEUE;
|
||||
return jsType >= JSType::JS_API_ARRAY_LIST && jsType <= JSType::JS_QUEUE;
|
||||
}
|
||||
|
||||
int32_t FastRuntimeStub::TryToElementsIndex(JSTaggedValue key)
|
||||
@ -1340,8 +1340,8 @@ JSTaggedValue FastRuntimeStub::GetContainerProperty(JSThread *thread, JSTaggedVa
|
||||
{
|
||||
JSTaggedValue res = JSTaggedValue::Undefined();
|
||||
switch (jsType) {
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
res = JSArrayList::Cast(receiver.GetTaggedObject())->Get(thread, index);
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
res = JSAPIArrayList::Cast(receiver.GetTaggedObject())->Get(thread, index);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1354,8 +1354,8 @@ JSTaggedValue FastRuntimeStub::SetContainerProperty(JSThread *thread, JSTaggedVa
|
||||
{
|
||||
JSTaggedValue res = JSTaggedValue::Undefined();
|
||||
switch (jsType) {
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
res = JSArrayList::Cast(receiver.GetTaggedObject())->Set(thread, index, value);
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
res = JSAPIArrayList::Cast(receiver.GetTaggedObject())->Set(thread, index, value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
391
ecmascript/js_api_arraylist.cpp
Normal file
391
ecmascript/js_api_arraylist.cpp
Normal file
@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "js_api_arraylist.h"
|
||||
#include "js_api_arraylist_iterator.h"
|
||||
#include "js_iterator.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/internal_call_params.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
bool JSAPIArrayList::Add(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value)
|
||||
{
|
||||
uint32_t length = arrayList->GetLength().GetArrayLength();
|
||||
JSHandle<TaggedArray> elements = GrowCapacity(thread, arrayList, length + 1);
|
||||
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
elements->Set(thread, length, value);
|
||||
arrayList->SetLength(thread, JSTaggedValue(++length));
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSAPIArrayList::Insert(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value, const int &index)
|
||||
{
|
||||
int length = static_cast<int>(arrayList->GetLength().GetArrayLength());
|
||||
if (index < 0 || index >= length) {
|
||||
THROW_RANGE_ERROR(thread, "ArrayList: set out-of-bounds");
|
||||
}
|
||||
JSHandle<TaggedArray> elements = GrowCapacity(thread, arrayList, length + 1);
|
||||
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
for (int i = length; i >= index; --i) {
|
||||
elements->Set(thread, i, elements->Get(i - 1));
|
||||
}
|
||||
elements->Set(thread, index, value);
|
||||
arrayList->SetLength(thread, JSTaggedValue(++length));
|
||||
}
|
||||
|
||||
void JSAPIArrayList::Clear(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList)
|
||||
{
|
||||
if (!arrayList.IsEmpty()) {
|
||||
arrayList->SetLength(thread, JSTaggedValue(0));
|
||||
}
|
||||
}
|
||||
|
||||
JSHandle<JSAPIArrayList> JSAPIArrayList::Clone(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
|
||||
{
|
||||
uint32_t length = obj->GetSize();
|
||||
JSHandle<TaggedArray> elements(thread, obj->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
uint32_t capacity = elements->GetLength();
|
||||
JSHandle<JSAPIArrayList> newArrayList = thread->GetEcmaVM()->GetFactory()->NewJSAPIArrayList(capacity);
|
||||
|
||||
newArrayList->SetLength(thread, JSTaggedValue(length));
|
||||
for (uint32_t i = 0; i < length; i ++) {
|
||||
newArrayList->Set(thread, i, elements->Get(i));
|
||||
}
|
||||
|
||||
return newArrayList;
|
||||
}
|
||||
|
||||
uint32_t JSAPIArrayList::GetCapacity(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
|
||||
{
|
||||
JSHandle<TaggedArray> elements(thread, obj->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
uint32_t capacity = elements->GetLength();
|
||||
return capacity;
|
||||
}
|
||||
|
||||
void JSAPIArrayList::IncreaseCapacityTo(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
int capacity)
|
||||
{
|
||||
JSHandle<TaggedArray> elementData(thread, arrayList->GetElements());
|
||||
ASSERT(!elementData->IsDictionaryMode());
|
||||
int length = static_cast<int>(arrayList->GetLength().GetArrayLength());
|
||||
if (length < capacity) {
|
||||
JSHandle<TaggedArray> newElements =
|
||||
thread->GetEcmaVM()->GetFactory()->CopyArray(elementData, length, capacity);
|
||||
|
||||
arrayList->SetElements(thread, newElements);
|
||||
}
|
||||
}
|
||||
|
||||
void JSAPIArrayList::TrimToCurrentLength(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList)
|
||||
{
|
||||
uint32_t length = arrayList->GetLength().GetArrayLength();
|
||||
JSHandle<TaggedArray> oldElements(thread, arrayList->GetElements());
|
||||
ASSERT(!oldElements->IsDictionaryMode());
|
||||
JSHandle<TaggedArray> newElements = thread->GetEcmaVM()->GetFactory()->CopyArray(oldElements, length, length);
|
||||
arrayList->SetElements(thread, newElements);
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIArrayList::Get(JSThread *thread, const uint32_t index)
|
||||
{
|
||||
if (index < 0 || index >= GetLength().GetArrayLength()) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Get property index out-of-bounds", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
|
||||
return elements->Get(index);
|
||||
}
|
||||
|
||||
bool JSAPIArrayList::IsEmpty(const JSHandle<JSAPIArrayList> &arrayList)
|
||||
{
|
||||
return arrayList->GetLength().GetArrayLength() == 0;
|
||||
}
|
||||
|
||||
int JSAPIArrayList::GetIndexOf(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value)
|
||||
{
|
||||
JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
uint32_t length = arrayList->GetLength().GetArrayLength();
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
JSHandle<JSTaggedValue> element(thread, elements->Get(i));
|
||||
if (JSTaggedValue::StrictEqual(thread, value, element)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int JSAPIArrayList::GetLastIndexOf(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value)
|
||||
{
|
||||
JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
uint32_t length = arrayList->GetLength().GetArrayLength();
|
||||
for (int i = length - 1; i >= 0; --i) {
|
||||
JSHandle<JSTaggedValue> element(thread, elements->Get(i));
|
||||
if (JSTaggedValue::StrictEqual(thread, value, element)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool JSAPIArrayList::RemoveByIndex(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList, int index)
|
||||
{
|
||||
int length = arrayList->GetLength().GetArrayLength();
|
||||
int curLength = static_cast<int>(length);
|
||||
if (index < 0 || index >= length) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "removeByIndex is out-of-bounds", false);
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
for (int i = index; i <= length - 2; i++) { // 2 : 2 get index of (lastElementIndex - 1)
|
||||
elements->Set(thread, i, elements->Get(i + 1));
|
||||
}
|
||||
|
||||
arrayList->SetLength(thread, JSTaggedValue(--curLength));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSAPIArrayList::Remove(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value)
|
||||
{
|
||||
int index = GetIndexOf(thread, arrayList, value);
|
||||
uint32_t length = arrayList->GetSize();
|
||||
int curLength = static_cast<int>(length);
|
||||
if (index >= 0) {
|
||||
if (index >= curLength) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "index-out-of-bounds", false);
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
for (uint32_t i = index; i < length - 1; i++) {
|
||||
elements->Set(thread, i, elements->Get(i + 1));
|
||||
}
|
||||
length--;
|
||||
arrayList->SetLength(thread, JSTaggedValue(length));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIArrayList::RemoveByRange(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value1,
|
||||
const JSHandle<JSTaggedValue> &value2)
|
||||
{
|
||||
int startIndex = JSTaggedValue::ToInt32(thread, value1);
|
||||
int endIndex = JSTaggedValue::ToInt32(thread, value2);
|
||||
int length = static_cast<int>(arrayList->GetLength().GetArrayLength());
|
||||
if (endIndex <= startIndex) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "fromIndex cannot be less than or equal to toIndex",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
if (startIndex < 0 || startIndex >= length || endIndex < 0) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "ArrayList: set out-of-bounds", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
int toIndex = endIndex >= length - 1 ? length - 1 : endIndex;
|
||||
|
||||
JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
uint32_t numMoved = length - toIndex;
|
||||
for (uint32_t i = 0; i <= numMoved; i++) {
|
||||
elements->Set(thread, startIndex + i, elements->Get(toIndex + i));
|
||||
}
|
||||
|
||||
int newLength = length - (toIndex - startIndex);
|
||||
arrayList->SetLength(thread, JSTaggedValue(newLength));
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIArrayList::ReplaceAllElements(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
|
||||
const JSHandle<JSTaggedValue> &callbackFn,
|
||||
const JSHandle<JSTaggedValue> &thisArg)
|
||||
{
|
||||
JSHandle<JSAPIArrayList> arraylist = JSHandle<JSAPIArrayList>::Cast(thisHandle);
|
||||
uint32_t length = arraylist->GetSize();
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
InternalCallParams *arguments = thread->GetInternalCallParams();
|
||||
|
||||
for (uint32_t k = 0; k < length; k++) {
|
||||
JSHandle<JSTaggedValue> kValue = JSHandle<JSTaggedValue>(thread, arraylist->Get(thread, k));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
key.Update(JSTaggedValue(k));
|
||||
arguments->MakeArgv(kValue, key, thisHandle);
|
||||
JSTaggedValue funcResult =
|
||||
JSFunction::Call(thread, callbackFn, thisArg, 3, arguments->GetArgv()); // 3: three args
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
|
||||
|
||||
arraylist->Set(thread, k, funcResult);
|
||||
}
|
||||
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIArrayList::Set(JSThread *thread, const uint32_t index, JSTaggedValue value)
|
||||
{
|
||||
if (index < 0 || index >= GetLength().GetArrayLength()) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Set property index out-of-bounds", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
|
||||
elements->Set(thread, index, value);
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
JSHandle<JSAPIArrayList> JSAPIArrayList::SubArrayList(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value1,
|
||||
const JSHandle<JSTaggedValue> &value2)
|
||||
{
|
||||
int length = static_cast<int>(arrayList->GetLength().GetArrayLength());
|
||||
int fromIndex = JSTaggedValue::ToInt32(thread, value1);
|
||||
int toIndex = JSTaggedValue::ToInt32(thread, value2);
|
||||
if (toIndex <= fromIndex) {
|
||||
JSHandle<JSAPIArrayList> newArrayList = thread->GetEcmaVM()->GetFactory()->NewJSAPIArrayList(0);
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "fromIndex cannot be less than or equal to toIndex", newArrayList);
|
||||
}
|
||||
if (fromIndex < 0 || fromIndex >= length || toIndex < 0) {
|
||||
JSHandle<JSAPIArrayList> newArrayList = thread->GetEcmaVM()->GetFactory()->NewJSAPIArrayList(0);
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "fromIndex or toIndex is out-of-bounds", newArrayList);
|
||||
}
|
||||
|
||||
int endIndex = toIndex >= length - 1 ? length - 1 : toIndex;
|
||||
if (fromIndex > endIndex) {
|
||||
int tmp = fromIndex;
|
||||
fromIndex = endIndex;
|
||||
endIndex = tmp;
|
||||
}
|
||||
|
||||
int newLength = endIndex - fromIndex;
|
||||
JSHandle<JSAPIArrayList> subArrayList =
|
||||
thread->GetEcmaVM()->GetFactory()->NewJSAPIArrayList(newLength);
|
||||
JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
subArrayList->SetLength(thread, JSTaggedValue(newLength));
|
||||
|
||||
for (int i = 0; i < newLength; i++) {
|
||||
subArrayList->Set(thread, i, elements->Get(fromIndex + i));
|
||||
}
|
||||
|
||||
return subArrayList;
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIArrayList::ForEach(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
|
||||
const JSHandle<JSTaggedValue> &callbackFn,
|
||||
const JSHandle<JSTaggedValue> &thisArg)
|
||||
{
|
||||
JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(thisHandle);
|
||||
uint32_t length = arrayList->GetSize();
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
InternalCallParams *arguments = thread->GetInternalCallParams();
|
||||
|
||||
for (uint32_t k = 0; k < length; k++) {
|
||||
JSHandle<JSTaggedValue> kValue = JSHandle<JSTaggedValue>(thread, arrayList->Get(thread, k));
|
||||
|
||||
key.Update(JSTaggedValue(k));
|
||||
arguments->MakeArgv(kValue, key, thisHandle);
|
||||
JSTaggedValue funcResult =
|
||||
JSFunction::Call(thread, callbackFn, thisArg, 3, arguments->GetArgv()); // 3: three args
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
|
||||
if (length != arrayList->GetSize()) {
|
||||
length = arrayList->GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> JSAPIArrayList::GrowCapacity(const JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
|
||||
uint32_t capacity)
|
||||
{
|
||||
JSHandle<TaggedArray> oldElements(thread, obj->GetElements());
|
||||
ASSERT(!oldElements->IsDictionaryMode());
|
||||
uint32_t oldCapacity = oldElements->GetLength();
|
||||
if (capacity < oldCapacity) {
|
||||
return oldElements;
|
||||
}
|
||||
uint32_t newCapacity = ComputeCapacity(capacity);
|
||||
JSHandle<TaggedArray> newElements =
|
||||
thread->GetEcmaVM()->GetFactory()->CopyArray(oldElements, oldCapacity, newCapacity);
|
||||
|
||||
obj->SetElements(thread, newElements);
|
||||
return newElements;
|
||||
}
|
||||
|
||||
bool JSAPIArrayList::Has(JSTaggedValue value) const
|
||||
{
|
||||
TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
|
||||
uint32_t length = GetSize();
|
||||
if (length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
if (JSTaggedValue::SameValue(elements->Get(i), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> JSAPIArrayList::OwnKeys(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
|
||||
{
|
||||
uint32_t length = obj->GetLength().GetArrayLength();
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> keys = factory->NewTaggedArray(length);
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
keys->Set(thread, i, JSTaggedValue(i));
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
bool JSAPIArrayList::GetOwnProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, PropertyDescriptor &desc)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
if (UNLIKELY(JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Can not obtain attributes of no-number type", false);
|
||||
}
|
||||
|
||||
uint32_t length = obj->GetLength().GetArrayLength();
|
||||
if (index < 0 || index >= length) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "GetOwnProperty index out-of-bounds", false);
|
||||
}
|
||||
return JSObject::GetOwnProperty(thread, JSHandle<JSObject>::Cast(obj), key, desc);
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIArrayList::GetIteratorObj(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<JSAPIArrayListIterator> iter(factory->NewJSAPIArrayListIterator(obj));
|
||||
|
||||
return iter.GetTaggedValue();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
95
ecmascript/js_api_arraylist.h
Normal file
95
ecmascript/js_api_arraylist.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_JS_APIARRAYLIST_H
|
||||
#define ECMASCRIPT_JS_APIARRAYLIST_H
|
||||
|
||||
#include "js_object.h"
|
||||
#include "js_tagged_value-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
/**
|
||||
* Provide the object of non ECMA standard jsapi container.
|
||||
* JSAPIArrayList provides dynamically modified array.
|
||||
* */
|
||||
class JSAPIArrayList : public JSObject {
|
||||
public:
|
||||
static constexpr int DEFAULT_CAPACITY_LENGTH = 10;
|
||||
static JSAPIArrayList *Cast(ObjectHeader *object)
|
||||
{
|
||||
ASSERT(JSTaggedValue(object).IsJSAPIArrayList());
|
||||
return static_cast<JSAPIArrayList *>(object);
|
||||
}
|
||||
|
||||
static bool Add(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList, const JSHandle<JSTaggedValue> &value);
|
||||
static void Insert(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value, const int &index);
|
||||
static void Clear(JSThread *thread, const JSHandle<JSAPIArrayList> &obj);
|
||||
static JSHandle<JSAPIArrayList> Clone(JSThread *thread, const JSHandle<JSAPIArrayList> &obj);
|
||||
static uint32_t GetCapacity(JSThread *thread, const JSHandle<JSAPIArrayList> &obj);
|
||||
static void IncreaseCapacityTo(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
int capacity);
|
||||
static void TrimToCurrentLength(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList);
|
||||
static bool IsEmpty(const JSHandle<JSAPIArrayList> &arrayList);
|
||||
static int GetIndexOf(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static int GetLastIndexOf(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static bool RemoveByIndex(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList, int value);
|
||||
static bool Remove(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static JSTaggedValue RemoveByRange(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value1, const JSHandle<JSTaggedValue> &value2);
|
||||
static JSTaggedValue ReplaceAllElements(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
|
||||
const JSHandle<JSTaggedValue> &callbackFn,
|
||||
const JSHandle<JSTaggedValue> &thisArg);
|
||||
static JSHandle<JSAPIArrayList> SubArrayList(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
|
||||
const JSHandle<JSTaggedValue> &value1,
|
||||
const JSHandle<JSTaggedValue> &value2);
|
||||
static JSTaggedValue ForEach(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
|
||||
const JSHandle<JSTaggedValue> &callbackFn,
|
||||
const JSHandle<JSTaggedValue> &thisArg);
|
||||
|
||||
static JSTaggedValue GetIteratorObj(JSThread *thread, const JSHandle<JSAPIArrayList> &obj);
|
||||
|
||||
JSTaggedValue Set(JSThread *thread, const uint32_t index, JSTaggedValue value);
|
||||
JSTaggedValue Get(JSThread *thread, const uint32_t index);
|
||||
|
||||
bool Has(JSTaggedValue value) const;
|
||||
static JSHandle<TaggedArray> OwnKeys(JSThread *thread, const JSHandle<JSAPIArrayList> &obj);
|
||||
static bool GetOwnProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, PropertyDescriptor &desc);
|
||||
inline int GetSize() const
|
||||
{
|
||||
return GetLength().GetArrayLength();
|
||||
}
|
||||
|
||||
static constexpr size_t LENGTH_OFFSET = JSObject::SIZE;
|
||||
ACCESSORS(Length, LENGTH_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LENGTH_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
private:
|
||||
inline static uint32_t ComputeCapacity(uint32_t oldCapacity)
|
||||
{
|
||||
uint32_t newCapacity = oldCapacity + (oldCapacity >> 1U);
|
||||
return newCapacity > DEFAULT_CAPACITY_LENGTH ? newCapacity : DEFAULT_CAPACITY_LENGTH;
|
||||
}
|
||||
static JSHandle<TaggedArray> GrowCapacity(const JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
|
||||
uint32_t capacity);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_JS_APIARRAYLIST_H
|
62
ecmascript/js_api_arraylist_iterator.cpp
Normal file
62
ecmascript/js_api_arraylist_iterator.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "js_api_arraylist_iterator.h"
|
||||
#include "builtins/builtins_errors.h"
|
||||
#include "ecmascript/base/typed_array_helper-inl.h"
|
||||
#include "ecmascript/base/typed_array_helper.h"
|
||||
#include "global_env.h"
|
||||
#include "js_api_arraylist.h"
|
||||
#include "object_factory.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using BuiltinsBase = base::BuiltinsBase;
|
||||
// ArrayListIteratorPrototype%.next ( )
|
||||
JSTaggedValue JSAPIArrayListIterator::Next(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> input(BuiltinsBase::GetThis(argv));
|
||||
if (!input->IsJSAPIArrayListIterator()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "this value is not an arrayList iterator", JSTaggedValue::Exception());
|
||||
}
|
||||
JSHandle<JSAPIArrayListIterator> iter(input);
|
||||
JSHandle<JSTaggedValue> arrayList(thread, iter->GetIteratedArrayList());
|
||||
JSHandle<JSTaggedValue> undefinedHandle = thread->GlobalConstants()->GetHandledUndefined();
|
||||
|
||||
if (arrayList->IsUndefined()) {
|
||||
return JSIterator::CreateIterResultObject(thread, undefinedHandle, true).GetTaggedValue();
|
||||
}
|
||||
|
||||
uint32_t index = iter->GetNextIndex().GetInt();
|
||||
uint32_t length = 0;
|
||||
|
||||
if (arrayList->IsJSAPIArrayList()) {
|
||||
length = JSHandle<JSAPIArrayList>(arrayList)->GetLength().GetArrayLength();
|
||||
}
|
||||
|
||||
if (index >= length) {
|
||||
iter->SetIteratedArrayList(thread, undefinedHandle);
|
||||
return JSIterator::CreateIterResultObject(thread, undefinedHandle, true).GetTaggedValue();
|
||||
}
|
||||
|
||||
iter->SetNextIndex(thread, JSTaggedValue(index + 1));
|
||||
JSHandle<JSTaggedValue> value = JSTaggedValue::GetProperty(thread, arrayList, index).GetValue();
|
||||
|
||||
return JSIterator::CreateIterResultObject(thread, value, false).GetTaggedValue();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
46
ecmascript/js_api_arraylist_iterator.h
Normal file
46
ecmascript/js_api_arraylist_iterator.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_JS_API_ARRAYLIST_ITERATOR_H
|
||||
#define ECMASCRIPT_JS_API_ARRAYLIST_ITERATOR_H
|
||||
|
||||
#include "js_iterator.h"
|
||||
#include "js_object.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
/**
|
||||
* It is used to provide iterators for non ECMA standard jsapi containers.
|
||||
* JSAPIArrayListIterator provides ordered iterators.
|
||||
* */
|
||||
class JSAPIArrayListIterator : public JSObject {
|
||||
public:
|
||||
static JSAPIArrayListIterator *Cast(ObjectHeader *obj)
|
||||
{
|
||||
ASSERT(JSTaggedValue(obj).IsJSAPIArrayListIterator());
|
||||
return static_cast<JSAPIArrayListIterator *>(obj);
|
||||
}
|
||||
static JSTaggedValue Next(EcmaRuntimeCallInfo *argv);
|
||||
|
||||
static constexpr size_t ITERATED_ARRAYLIST_OFFSET = JSObject::SIZE;
|
||||
ACCESSORS(IteratedArrayList, ITERATED_ARRAYLIST_OFFSET, NEXT_INDEX_OFFSET)
|
||||
ACCESSORS(NextIndex, NEXT_INDEX_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ITERATED_ARRAYLIST_OFFSET, SIZE)
|
||||
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_JS_API_ARRAYLIST_ITERATOR_H
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "js_arraylist.h"
|
||||
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void JSArrayList::Add(JSThread *thread, const JSHandle<JSArrayList> &arrayList, const JSHandle<JSTaggedValue> &value)
|
||||
{
|
||||
// GrowCapacity
|
||||
uint32_t length = arrayList->GetLength().GetArrayLength();
|
||||
JSHandle<TaggedArray> elements = GrowCapacity(thread, arrayList, length + 1);
|
||||
|
||||
ASSERT(!elements->IsDictionaryMode());
|
||||
elements->Set(thread, length, value);
|
||||
arrayList->SetLength(thread, JSTaggedValue(++length));
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> JSArrayList::GrowCapacity(const JSThread *thread, const JSHandle<JSArrayList> &obj,
|
||||
uint32_t capacity)
|
||||
{
|
||||
JSHandle<TaggedArray> oldElements(thread, obj->GetElements());
|
||||
uint32_t oldLength = oldElements->GetLength();
|
||||
if (capacity < oldLength) {
|
||||
return oldElements;
|
||||
}
|
||||
uint32_t newCapacity = ComputeCapacity(capacity);
|
||||
JSHandle<TaggedArray> newElements =
|
||||
thread->GetEcmaVM()->GetFactory()->CopyArray(oldElements, oldLength, newCapacity);
|
||||
|
||||
obj->SetElements(thread, newElements);
|
||||
return newElements;
|
||||
}
|
||||
|
||||
JSTaggedValue JSArrayList::Get(JSThread *thread, const uint32_t index)
|
||||
{
|
||||
if (index < 0 || index >= GetLength().GetArrayLength()) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Get property index out-of-bounds", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
|
||||
return elements->Get(index);
|
||||
}
|
||||
|
||||
JSTaggedValue JSArrayList::Set(JSThread *thread, const uint32_t index, JSTaggedValue value)
|
||||
{
|
||||
if (index < 0 || index >= GetLength().GetArrayLength()) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Set property index out-of-bounds", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
|
||||
elements->Set(thread, index, value);
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
bool JSArrayList::Delete(JSThread *thread, const JSHandle<JSArrayList> &obj, const JSHandle<JSTaggedValue> &key)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
if (UNLIKELY(JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Can not delete a type other than number", false);
|
||||
}
|
||||
uint32_t length = obj->GetLength().GetArrayLength();
|
||||
if (index < 0 || index >= length) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Delete property index out-of-bounds", false);
|
||||
}
|
||||
TaggedArray *elements = TaggedArray::Cast(obj->GetElements().GetTaggedObject());
|
||||
for (uint32_t i = 0; i < length - 1; i++) {
|
||||
elements->Set(thread, i, elements->Get(i + 1));
|
||||
}
|
||||
obj->SetLength(thread, JSTaggedValue(--length));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSArrayList::Has(JSTaggedValue value) const
|
||||
{
|
||||
TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
|
||||
return !(elements->GetIdx(value) == TaggedArray::MAX_ARRAY_INDEX);
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> JSArrayList::OwnKeys(JSThread *thread, const JSHandle<JSArrayList> &obj)
|
||||
{
|
||||
uint32_t length = obj->GetLength().GetArrayLength();
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> keys = factory->NewTaggedArray(length);
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
keys->Set(thread, i, JSTaggedValue(i));
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
bool JSArrayList::GetOwnProperty(JSThread *thread, const JSHandle<JSArrayList> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, PropertyDescriptor &desc)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
if (UNLIKELY(JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Can not get property whose type is not number", false);
|
||||
}
|
||||
|
||||
uint32_t length = obj->GetLength().GetArrayLength();
|
||||
if (index < 0 || index >= length) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Get property index out-of-bounds", false);
|
||||
}
|
||||
return JSObject::GetOwnProperty(thread, JSHandle<JSObject>::Cast(obj), key, desc);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_JSARRAYLIST_H
|
||||
#define ECMASCRIPT_JSARRAYLIST_H
|
||||
|
||||
#include "js_object.h"
|
||||
#include "js_tagged_value-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JSArrayList : public JSObject {
|
||||
public:
|
||||
static constexpr int DEFAULT_CAPACITY_LENGTH = 10;
|
||||
static JSArrayList *Cast(ObjectHeader *object)
|
||||
{
|
||||
return static_cast<JSArrayList *>(object);
|
||||
}
|
||||
|
||||
static void Add(JSThread *thread, const JSHandle<JSArrayList> &arrayList, const JSHandle<JSTaggedValue> &value);
|
||||
|
||||
JSTaggedValue Get(JSThread *thread, const uint32_t index);
|
||||
|
||||
JSTaggedValue Set(JSThread *thread, const uint32_t index, JSTaggedValue value);
|
||||
bool Has(JSTaggedValue value) const;
|
||||
|
||||
static bool Delete(JSThread *thread, const JSHandle<JSArrayList> &obj, const JSHandle<JSTaggedValue> &key);
|
||||
static JSHandle<TaggedArray> OwnKeys(JSThread *thread, const JSHandle<JSArrayList> &obj);
|
||||
static bool GetOwnProperty(JSThread *thread, const JSHandle<JSArrayList> &obj, const JSHandle<JSTaggedValue> &key,
|
||||
PropertyDescriptor &desc);
|
||||
|
||||
inline int GetSize() const
|
||||
{
|
||||
return GetLength().GetArrayLength();
|
||||
}
|
||||
|
||||
static constexpr size_t LENGTH_OFFSET = JSObject::SIZE;
|
||||
ACCESSORS(Length, LENGTH_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LENGTH_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
private:
|
||||
inline static uint32_t ComputeCapacity(uint32_t oldCapacity)
|
||||
{
|
||||
uint32_t newCapacity = oldCapacity + (oldCapacity >> 1U);
|
||||
return newCapacity > DEFAULT_CAPACITY_LENGTH ? newCapacity : DEFAULT_CAPACITY_LENGTH;
|
||||
}
|
||||
static JSHandle<TaggedArray> GrowCapacity(const JSThread *thread, const JSHandle<JSArrayList> &obj,
|
||||
uint32_t capacity);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_JSARRAYLIST_H
|
@ -93,6 +93,7 @@ class ProtoChangeDetails;
|
||||
JS_FORIN_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_MAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_SET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_ARRAYLIST_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_TREEMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_TREESET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_ARRAY_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
@ -114,7 +115,8 @@ class ProtoChangeDetails;
|
||||
\
|
||||
/* SPECIAL indexed objects begin, DON'T CHANGE HERE ///////////////////////////////////////////////-PADDING */ \
|
||||
JS_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_VECTOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_TREE_MAP, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_API_TREE_SET, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_QUEUE, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
@ -605,11 +607,15 @@ public:
|
||||
// non ECMA standard jsapi containers.
|
||||
inline bool IsSpecialContainer() const
|
||||
{
|
||||
return GetObjectType() >= JSType::JS_ARRAY_LIST && GetObjectType() <= JSType::JS_QUEUE;
|
||||
return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_QUEUE;
|
||||
}
|
||||
inline bool IsJSArrayList() const
|
||||
inline bool IsJSAPIArrayList() const
|
||||
{
|
||||
return GetObjectType() == JSType::JS_ARRAY_LIST;
|
||||
return GetObjectType() == JSType::JS_API_ARRAY_LIST;
|
||||
}
|
||||
inline bool IsJSAPIArrayListIterator() const
|
||||
{
|
||||
return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR;
|
||||
}
|
||||
inline bool IsJSQueue() const
|
||||
{
|
||||
@ -682,6 +688,7 @@ public:
|
||||
{
|
||||
return GetObjectType() == JSType::JS_ARRAY_ITERATOR;
|
||||
}
|
||||
|
||||
inline bool IsPrototypeHandler() const
|
||||
{
|
||||
return GetObjectType() == JSType::PROTOTYPE_HANDLER;
|
||||
|
@ -176,6 +176,11 @@ inline bool JSObject::IsJSArrayIterator() const
|
||||
return GetJSHClass()->IsJSArrayIterator();
|
||||
}
|
||||
|
||||
inline bool JSObject::IsJSAPIArrayListIterator() const
|
||||
{
|
||||
return GetJSHClass()->IsJSAPIArrayListIterator();
|
||||
}
|
||||
|
||||
inline bool JSObject::IsJSPrimitiveRef() const
|
||||
{
|
||||
return GetJSHClass()->IsJsPrimitiveRef();
|
||||
|
@ -542,6 +542,7 @@ public:
|
||||
bool IsJSSetIterator() const;
|
||||
bool IsJSMapIterator() const;
|
||||
bool IsJSArrayIterator() const;
|
||||
bool IsJSAPIArrayListIterator() const;
|
||||
bool IsJSPrimitiveRef() const;
|
||||
bool IsElementDict() const;
|
||||
bool IsPropertiesDict() const;
|
||||
|
@ -497,9 +497,9 @@ inline bool JSTaggedValue::IsJSPluralRules() const
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPluralRules();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsJSArrayList() const
|
||||
inline bool JSTaggedValue::IsJSAPIArrayList() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSArrayList();
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIArrayList();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsJSAPITreeMap() const
|
||||
@ -795,6 +795,11 @@ inline bool JSTaggedValue::IsJSArrayIterator() const
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSArrayIterator();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsJSAPIArrayListIterator() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIArrayListIterator();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsIterator() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsIterator();
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/internal_call_params.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/js_primitive_ref.h"
|
||||
#include "ecmascript/js_proxy.h"
|
||||
@ -779,8 +779,8 @@ bool JSTaggedValue::HasContainerProperty(JSThread *thread, const JSHandle<JSTagg
|
||||
auto *hclass = obj->GetTaggedObject()->GetClass();
|
||||
JSType jsType = hclass->GetObjectType();
|
||||
switch (jsType) {
|
||||
case JSType::JS_ARRAY_LIST: {
|
||||
return JSHandle<JSArrayList>::Cast(obj)->Has(key.GetTaggedValue());
|
||||
case JSType::JS_API_ARRAY_LIST: {
|
||||
return JSHandle<JSAPIArrayList>::Cast(obj)->Has(key.GetTaggedValue());
|
||||
}
|
||||
case JSType::JS_QUEUE:
|
||||
break;
|
||||
@ -800,8 +800,8 @@ JSHandle<TaggedArray> JSTaggedValue::GetOwnContainerPropertyKeys(JSThread *threa
|
||||
auto *hclass = obj->GetTaggedObject()->GetClass();
|
||||
JSType jsType = hclass->GetObjectType();
|
||||
switch (jsType) {
|
||||
case JSType::JS_ARRAY_LIST: {
|
||||
return JSArrayList::OwnKeys(thread, JSHandle<JSArrayList>::Cast(obj));
|
||||
case JSType::JS_API_ARRAY_LIST: {
|
||||
return JSAPIArrayList::OwnKeys(thread, JSHandle<JSAPIArrayList>::Cast(obj));
|
||||
}
|
||||
case JSType::JS_QUEUE:
|
||||
break;
|
||||
@ -822,8 +822,8 @@ bool JSTaggedValue::GetContainerProperty(JSThread *thread, const JSHandle<JSTagg
|
||||
auto *hclass = obj->GetTaggedObject()->GetClass();
|
||||
JSType jsType = hclass->GetObjectType();
|
||||
switch (jsType) {
|
||||
case JSType::JS_ARRAY_LIST: {
|
||||
return JSArrayList::GetOwnProperty(thread, JSHandle<JSArrayList>::Cast(obj), key, desc);
|
||||
case JSType::JS_API_ARRAY_LIST: {
|
||||
return JSAPIArrayList::GetOwnProperty(thread, JSHandle<JSAPIArrayList>::Cast(obj), key, desc);
|
||||
}
|
||||
case JSType::JS_QUEUE:
|
||||
break;
|
||||
|
@ -317,7 +317,8 @@ public:
|
||||
bool IsJSPluralRules() const;
|
||||
|
||||
// non ECMA standard jsapis
|
||||
bool IsJSArrayList() const;
|
||||
bool IsJSAPIArrayList() const;
|
||||
bool IsJSAPIArrayListIterator() const;
|
||||
bool IsJSAPITreeMap() const;
|
||||
bool IsJSAPITreeSet() const;
|
||||
bool IsJSAPITreeMapIterator() const;
|
||||
|
@ -32,7 +32,8 @@
|
||||
#include "ecmascript/js_api_tree_set_iterator.h"
|
||||
#include "ecmascript/js_arguments.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
@ -300,8 +301,11 @@ void ObjectXRay::VisitObjectBody(TaggedObject *object, JSHClass *klass, const Ec
|
||||
ClassInfoExtractor::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_QUEUE:
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
JSArrayList::Cast(object)->VisitRangeSlot(visitor);
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
JSAPIArrayList::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR:
|
||||
JSAPIArrayListIterator::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_API_TREE_MAP:
|
||||
JSAPITreeMap::Cast(object)->VisitRangeSlot(visitor);
|
||||
|
@ -44,7 +44,8 @@
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_date.h"
|
||||
@ -774,8 +775,8 @@ JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunc
|
||||
JSDataView::Cast(*obj)->SetByteOffset(0);
|
||||
break;
|
||||
// non ECMA standard jsapi container
|
||||
case JSType::JS_ARRAY_LIST:
|
||||
JSArrayList::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
|
||||
case JSType::JS_API_ARRAY_LIST:
|
||||
JSAPIArrayList::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
|
||||
break;
|
||||
case JSType::JS_API_TREE_MAP:
|
||||
JSAPITreeMap::Cast(*obj)->SetTreeMap(thread_, JSTaggedValue::Undefined());
|
||||
@ -788,6 +789,7 @@ JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunc
|
||||
case JSType::JS_FORIN_ITERATOR:
|
||||
case JSType::JS_MAP_ITERATOR:
|
||||
case JSType::JS_SET_ITERATOR:
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR:
|
||||
case JSType::JS_API_TREEMAP_ITERATOR:
|
||||
case JSType::JS_API_TREESET_ITERATOR:
|
||||
case JSType::JS_ARRAY_ITERATOR:
|
||||
@ -2163,6 +2165,31 @@ JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const JSHandle<Ecma
|
||||
return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(firstString, secondString));
|
||||
}
|
||||
|
||||
JSHandle<JSAPIArrayList> ObjectFactory::NewJSAPIArrayList(uint32_t capacity)
|
||||
{
|
||||
NewObjectHook();
|
||||
JSHandle<JSTaggedValue> builtinObj(thread_, thread_->GlobalConstants()->GetArrayListFunction());
|
||||
JSHandle<JSAPIArrayList> obj =
|
||||
JSHandle<JSAPIArrayList>(NewJSObjectByConstructor(JSHandle<JSFunction>(builtinObj), builtinObj));
|
||||
ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
|
||||
obj->SetElements(thread_, factory->NewTaggedArray(capacity));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSHandle<JSAPIArrayListIterator> ObjectFactory::NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> &arrayList)
|
||||
{
|
||||
NewObjectHook();
|
||||
JSHandle<JSTaggedValue> protoValue(thread_, thread_->GlobalConstants()->GetArrayListIteratorPrototype());
|
||||
JSHandle<JSHClass> dynHandle =
|
||||
NewEcmaDynClass(JSAPIArrayListIterator::SIZE, JSType::JS_API_ARRAYLIST_ITERATOR, protoValue);
|
||||
JSHandle<JSAPIArrayListIterator> iter(NewJSObject(dynHandle));
|
||||
iter->GetJSHClass()->SetExtensible(true);
|
||||
iter->SetIteratedArrayList(thread_, arrayList);
|
||||
iter->SetNextIndex(thread_, JSTaggedValue(0));
|
||||
return iter;
|
||||
}
|
||||
|
||||
JSHandle<JSAPITreeMapIterator> ObjectFactory::NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> &map,
|
||||
IterationKind kind)
|
||||
{
|
||||
|
@ -82,6 +82,8 @@ class LayoutInfo;
|
||||
class JSIntlBoundFunction;
|
||||
class FreeObject;
|
||||
class JSNativePointer;
|
||||
class JSAPIArrayList;
|
||||
class JSAPIArrayListIterator;
|
||||
class JSAPITreeSet;
|
||||
class JSAPITreeMap;
|
||||
class JSAPITreeSetIterator;
|
||||
@ -363,6 +365,8 @@ public:
|
||||
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype);
|
||||
|
||||
// It is used to provide iterators for non ECMA standard jsapi containers.
|
||||
JSHandle<JSAPIArrayList> NewJSAPIArrayList(uint32_t capacity);
|
||||
JSHandle<JSAPIArrayListIterator> NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> &arrayList);
|
||||
JSHandle<JSAPITreeMapIterator> NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> &map, IterationKind kind);
|
||||
JSHandle<JSAPITreeSetIterator> NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> &set, IterationKind kind);
|
||||
|
||||
|
@ -517,7 +517,28 @@ namespace panda::ecmascript {
|
||||
V(WeakSet, Has) \
|
||||
V(ArrayList, Constructor) \
|
||||
V(ArrayList, Add) \
|
||||
V(ArrayList, Iterator) \
|
||||
V(ArrayList, Insert) \
|
||||
V(ArrayList, Clear) \
|
||||
V(ArrayList, Clone) \
|
||||
V(ArrayList, Has) \
|
||||
V(ArrayList, GetCapacity) \
|
||||
V(ArrayList, IncreaseCapacityTo) \
|
||||
V(ArrayList, TrimToCurrentLength) \
|
||||
V(ArrayList, GetIndexOf) \
|
||||
V(ArrayList, IsEmpty) \
|
||||
V(ArrayList, GetLastIndexOf) \
|
||||
V(ArrayList, RemoveByIndex) \
|
||||
V(ArrayList, Remove) \
|
||||
V(ArrayList, RemoveByRange) \
|
||||
V(ArrayList, ReplaceAllElements) \
|
||||
V(ArrayList, Sort) \
|
||||
V(ArrayList, SubArrayList) \
|
||||
V(ArrayList, ConvertToArray) \
|
||||
V(ArrayList, ForEach) \
|
||||
V(ArrayList, GetIteratorObj) \
|
||||
V(ArrayList, Get) \
|
||||
V(ArrayList, Set) \
|
||||
V(ArrayList, GetSize) \
|
||||
V(TreeMap, Constructor) \
|
||||
V(TreeMap, HasKey) \
|
||||
V(TreeMap, HasValue) \
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "ecmascript/ic/profile_type_info.h"
|
||||
#include "ecmascript/ic/properties_cache.h"
|
||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_object.h"
|
||||
#include "ecmascript/js_proxy.h"
|
||||
#include "ecmascript/layout_info.h"
|
||||
@ -1117,14 +1117,6 @@ JSTaggedType RuntimeTrampolines::Mod2Dyn(uintptr_t argGlue, JSTaggedType left, J
|
||||
return SlowRuntimeStub::Mod2Dyn(thread, JSTaggedValue(left), JSTaggedValue(right)).GetRawData();
|
||||
}
|
||||
|
||||
void RuntimeTrampolines::JSArrayListSetByIndex(uintptr_t argGlue, JSTaggedValue obj, int32_t index, JSTaggedValue value)
|
||||
{
|
||||
auto thread = JSThread::GlueToJSThread(argGlue);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSArrayList> arrayList(thread, obj);
|
||||
arrayList->Set(thread, index, value);
|
||||
}
|
||||
|
||||
void RuntimeTrampolines::InsertOldToNewRememberedSet([[maybe_unused]]uintptr_t argGlue, Region* region, uintptr_t addr)
|
||||
{
|
||||
return region->InsertOldToNewRememberedSet(addr);
|
||||
|
@ -178,7 +178,6 @@ public:
|
||||
static JSTaggedType Mul2Dyn(uintptr_t argGlue, JSTaggedType left, JSTaggedType right);
|
||||
static JSTaggedType Div2Dyn(uintptr_t argGlue, JSTaggedType left, JSTaggedType right);
|
||||
static JSTaggedType Mod2Dyn(uintptr_t argGlue, JSTaggedType left, JSTaggedType right);
|
||||
static void JSArrayListSetByIndex(uintptr_t argGlue, JSTaggedValue obj, int32_t index, JSTaggedValue value);
|
||||
static void InsertOldToNewRememberedSet([[maybe_unused]]uintptr_t argGlue, Region* region, uintptr_t addr);
|
||||
static void MarkingBarrier([[maybe_unused]]uintptr_t argGlue, uintptr_t slotAddr,
|
||||
Region *objectRegion, TaggedObject *value, Region *valueRegion);
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "ecmascript/js_api_tree_map_iterator.h"
|
||||
#include "ecmascript/js_api_tree_set_iterator.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/js_for_in_iterator.h"
|
||||
#include "ecmascript/js_hclass.h"
|
||||
#include "ecmascript/js_map_iterator.h"
|
||||
@ -556,7 +557,28 @@ static uintptr_t g_nativeTable[] = {
|
||||
// non ECMA standard jsapi containers.
|
||||
reinterpret_cast<uintptr_t>(ArrayList::ArrayListConstructor),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Add),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Iterator),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Insert),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Clear),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Clone),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Has),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::GetCapacity),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::IncreaseCapacityTo),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::TrimToCurrentLength),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::GetIndexOf),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::IsEmpty),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::GetLastIndexOf),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::RemoveByIndex),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Remove),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::RemoveByRange),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::ReplaceAllElements),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::SubArrayList),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::ConvertToArray),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::ForEach),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::GetIteratorObj),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Get),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::Set),
|
||||
reinterpret_cast<uintptr_t>(ArrayList::GetSize),
|
||||
reinterpret_cast<uintptr_t>(JSAPIArrayListIterator::Next),
|
||||
reinterpret_cast<uintptr_t>(TreeMap::TreeMapConstructor),
|
||||
reinterpret_cast<uintptr_t>(TreeMap::Set),
|
||||
reinterpret_cast<uintptr_t>(TreeMap::Get),
|
||||
|
@ -36,7 +36,8 @@
|
||||
#include "ecmascript/js_api_tree_set_iterator.h"
|
||||
#include "ecmascript/js_arguments.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist.h"
|
||||
#include "ecmascript/js_api_arraylist_iterator.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
@ -180,6 +181,16 @@ static JSHandle<JSObject> NewJSObject(JSThread *thread, ObjectFactory *factory,
|
||||
return jsObj;
|
||||
}
|
||||
|
||||
static JSHandle<JSAPIArrayList> NewJSAPIArrayList(JSThread *thread, ObjectFactory *factory,
|
||||
JSHandle<JSTaggedValue> proto)
|
||||
{
|
||||
JSHandle<JSHClass> arrayListClass =
|
||||
factory->NewEcmaDynClass(JSAPIArrayList::SIZE, JSType::JS_API_ARRAY_LIST, proto);
|
||||
JSHandle<JSAPIArrayList> jsArrayList = JSHandle<JSAPIArrayList>::Cast(factory->NewJSObject(arrayListClass));
|
||||
jsArrayList->SetLength(thread, JSTaggedValue(0));
|
||||
return jsArrayList;
|
||||
}
|
||||
|
||||
HWTEST_F_L0(EcmaDumpTest, HeapProfileDump)
|
||||
{
|
||||
[[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
|
||||
@ -645,9 +656,18 @@ HWTEST_F_L0(EcmaDumpTest, HeapProfileDump)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_QUEUE:
|
||||
case JSType::JS_ARRAY_LIST: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayList::SIZE, 1)
|
||||
// unused
|
||||
case JSType::JS_API_VECTOR:
|
||||
case JSType::JS_API_ARRAY_LIST: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSAPIArrayList::SIZE, 1)
|
||||
JSHandle<JSAPIArrayList> jsArrayList = NewJSAPIArrayList(thread, factory, proto);
|
||||
DUMP_FOR_HANDLE(jsArrayList)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_API_ARRAYLIST_ITERATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSAPIArrayListIterator::SIZE, 2)
|
||||
JSHandle<JSAPIArrayListIterator> jsArrayListIter =
|
||||
factory->NewJSAPIArrayListIterator(NewJSAPIArrayList(thread, factory, proto));
|
||||
DUMP_FOR_HANDLE(jsArrayListIter)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_API_TREE_MAP: {
|
||||
|
Loading…
Reference in New Issue
Block a user