!526 Add Container ArrayList

Merge pull request !526 from 刘甘霖/container_arraylist
This commit is contained in:
openharmony_ci 2022-02-18 09:53:09 +00:00 committed by Gitee
commit 74d4f0e409
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
35 changed files with 1332 additions and 338 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &notSpecialIndex);
Bind(&isSpecialIndex);
{
Label isSpecialContainer(env);
Label notSpecialContainer(env);
// Add SpecialContainer
Branch(IsSpecialContainer(jsType), &isSpecialContainer, &notSpecialContainer);
Bind(&isSpecialContainer);
{
returnValue = SetContainerProperty(glue, *holder, index, value, jsType);
Jump(&exit);
}
Bind(&notSpecialContainer);
{
returnValue = GetHoleConstant(StubMachineType::UINT64);
Jump(&exit);
}
returnValue = GetHoleConstant(StubMachineType::UINT64);
Jump(&exit);
}
Bind(&notSpecialIndex);
{
@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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