• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/js_api/js_api_list_iterator.h"
17 
18 #include "ecmascript/containers/containers_errors.h"
19 #include "ecmascript/js_api/js_api_list.h"
20 
21 namespace panda::ecmascript {
22 using BuiltinsBase = base::BuiltinsBase;
23 using ContainerError = containers::ContainerError;
24 using ErrorFlag = containers::ErrorFlag;
Next(EcmaRuntimeCallInfo * argv)25 JSTaggedValue JSAPIListIterator::Next(EcmaRuntimeCallInfo *argv)
26 {
27     ASSERT(argv);
28     JSThread *thread = argv->GetThread();
29     [[maybe_unused]] EcmaHandleScope handleScope(thread);
30     JSHandle<JSTaggedValue> input(BuiltinsBase::GetThis(argv));
31     if (!input->IsJSAPIListIterator()) {
32         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
33                                                             "The Symbol.iterator method cannot be bound");
34         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
35     }
36     JSHandle<JSAPIListIterator> iter(input);
37     JSHandle<JSTaggedValue> list(thread, iter->GetIteratedList());
38     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
39     JSHandle<TaggedSingleList> singleList(list);
40     if (list->IsUndefined()) {
41         return globalConst->GetUndefinedIterResult();
42     }
43     int index = static_cast<int>(iter->GetNextIndex());
44     int length = singleList->Length();
45     if (index >= length) {
46         JSHandle<JSTaggedValue> undefinedHandle = globalConst->GetHandledUndefined();
47         iter->SetIteratedList(thread, undefinedHandle);
48         return globalConst->GetUndefinedIterResult();
49     }
50     iter->SetNextIndex(index + 1);
51     int dataIndex = static_cast<int>(iter->GetDataIndex());
52     std::pair<int, JSTaggedValue> resultPair = singleList->GetByDataIndex(dataIndex);
53     iter->SetDataIndex(resultPair.first);
54     JSHandle<JSTaggedValue> value(thread, resultPair.second);
55     return JSIterator::CreateIterResultObject(thread, value, false).GetTaggedValue();
56 }
57 
CreateListIterator(JSThread * thread,JSHandle<JSTaggedValue> & obj)58 JSHandle<JSTaggedValue> JSAPIListIterator::CreateListIterator(JSThread *thread, JSHandle<JSTaggedValue> &obj)
59 {
60     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
61     if (!obj->IsJSAPIList()) {
62         if (obj->IsJSProxy() && JSHandle<JSProxy>::Cast(obj)->GetTarget().IsJSAPIList()) {
63             obj = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(obj)->GetTarget());
64         } else {
65             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
66                                                                 "The Symbol.iterator method cannot be bound");
67             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error,
68                                              JSHandle<JSTaggedValue>(thread, JSTaggedValue::Exception()));
69         }
70     }
71     JSHandle<JSTaggedValue> iter(factory->NewJSAPIListIterator(JSHandle<JSAPIList>(obj)));
72     return iter;
73 }
74 } // namespace panda::ecmascript
75