• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef ECMASCRIPT_ACCESSOR_DATA_H
17 #define ECMASCRIPT_ACCESSOR_DATA_H
18 
19 #include "ecmascript/ecma_macros.h"
20 #include "ecmascript/js_hclass.h"
21 #include "ecmascript/js_native_pointer.h"
22 #include "ecmascript/js_tagged_value.h"
23 #include "ecmascript/record.h"
24 
25 namespace panda::ecmascript {
26 class AccessorData final : public Record {
27 public:
28     using InternalGetFunc = JSTaggedValue (*)(JSThread *, const JSHandle<JSObject> &);
29     using InternalSetFunc = bool (*)(JSThread *, const JSHandle<JSObject> &, const JSHandle<JSTaggedValue> &, bool);
30 
Cast(ObjectHeader * object)31     static AccessorData *Cast(ObjectHeader *object)
32     {
33         ASSERT(JSTaggedValue(object).IsAccessorData() || JSTaggedValue(object).IsInternalAccessor());
34         return static_cast<AccessorData *>(object);
35     }
36 
IsInternal()37     inline bool IsInternal() const
38     {
39         return GetClass()->IsInternalAccessor();
40     }
41 
HasSetter()42     inline bool HasSetter() const
43     {
44         return !GetSetter().IsUndefined();
45     }
46 
CallInternalGet(JSThread * thread,const JSHandle<JSObject> & obj)47     JSTaggedValue CallInternalGet(JSThread *thread, const JSHandle<JSObject> &obj) const
48     {
49         ASSERT(GetGetter().IsJSNativePointer());
50         JSNativePointer *getter = JSNativePointer::Cast(GetGetter().GetTaggedObject());
51         auto getFunc = reinterpret_cast<InternalGetFunc>(getter->GetExternalPointer());
52         return getFunc(thread, obj);
53     }
54 
55     bool CallInternalSet(JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &value,
56                          bool mayThrow = false) const
57     {
58         ASSERT(GetSetter().IsJSNativePointer());
59         JSNativePointer *setter = JSNativePointer::Cast(GetSetter().GetTaggedObject());
60         auto setFunc = reinterpret_cast<InternalSetFunc>(setter->GetExternalPointer());
61         return setFunc(thread, obj, value, mayThrow);
62     }
63 
64     static constexpr size_t GETTER_OFFSET = Record::SIZE;
65     ACCESSORS(Getter, GETTER_OFFSET, SETTER_OFFSET);
66     ACCESSORS(Setter, SETTER_OFFSET, SIZE);
67 
68     DECL_DUMP()
69     DECL_VISIT_OBJECT(GETTER_OFFSET, SIZE)
70 };
71 
72 enum class CompletionRecordType : uint8_t {
73     NORMAL = 0U,
74     BREAK,
75     CONTINUE,
76     RETURN,
77     THROW
78 };
79 
80 class CompletionRecord final : public Record {
81 public:
Cast(ObjectHeader * object)82     static CompletionRecord *Cast(ObjectHeader *object)
83     {
84         ASSERT(JSTaggedValue(object).IsCompletionRecord());
85         return static_cast<CompletionRecord *>(object);
86     }
87 
IsThrow()88     bool IsThrow() const
89     {
90         return GetType() == CompletionRecordType::THROW;
91     }
92 
93     static constexpr size_t VALUE_OFFSET = Record::SIZE;
94     ACCESSORS(Value, VALUE_OFFSET, BIT_FIELD_OFFSET)
95     ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET)
96     DEFINE_ALIGN_SIZE(LAST_OFFSET);
97 
98     // define BitField
99     static constexpr size_t TYPE_BITS = 3;
100     FIRST_BIT_FIELD(BitField, Type, CompletionRecordType, TYPE_BITS)
101 
102     DECL_DUMP()
103 
104     DECL_VISIT_OBJECT(VALUE_OFFSET, BIT_FIELD_OFFSET)
105 };
106 }  // namespace panda::ecmascript
107 #endif  // ECMASCRIPT_ACCESSOR_DATA_H
108