• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H
17 #define ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H
18 
19 #include "ecmascript/builtins/builtins_arraybuffer.h"
20 #include "ecmascript/base/builtins_base.h"
21 #include "ecmascript/base/error_helper.h"
22 #include "ecmascript/base/error_type.h"
23 #include "ecmascript/base/typed_array_helper.h"
24 #include "ecmascript/ecma_macros.h"
25 #include "ecmascript/ecma_vm.h"
26 #include "ecmascript/global_env.h"
27 #include "ecmascript/ic/proto_change_details.h"
28 #include "ecmascript/js_array_iterator.h"
29 #include "ecmascript/js_arraybuffer.h"
30 #include "ecmascript/js_hclass.h"
31 #include "ecmascript/js_object.h"
32 #include "ecmascript/js_tagged_value.h"
33 #include "ecmascript/js_tagged_value-inl.h"
34 #include "ecmascript/object_factory.h"
35 
36 namespace panda::ecmascript::base {
37 
38 #define GET_ONHEAP_HCLASS_FROM_TYPE(Type)                                                          \
39 JSHandle<JSHClass> TypedArrayHelper::GetOnHeapHclass##Type(JSThread *thread, JSHClass* objHclass)  \
40 {                                                                                                  \
41     JSHandle<JSHClass> result;                                                                     \
42     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();                                 \
43     if (*JSHandle<JSHClass>(env->Get##Type##RootHclass()) == (objHclass)) {                        \
44         return JSHandle<JSHClass>(env->Get##Type##RootHclassOnHeap());                             \
45     }                                                                                              \
46     result = JSHClass::Clone((thread), JSHandle<JSHClass>((thread), (objHclass)));                 \
47     result->SetIsOnHeap(true);                                                                     \
48     return result;                                                                                 \
49 }
50 
51 TYPED_ARRAY_TYPES(GET_ONHEAP_HCLASS_FROM_TYPE)
52 #undef GET_ONHEAP_HCLASS_FROM_TYPE
53 
54 #define GET_NOT_ONHEAP_HCLASS_FROM_TYPE(Type)                                                          \
55 JSHandle<JSHClass> TypedArrayHelper::GetNotOnHeapHclass##Type(JSThread *thread, JSHClass* objHclass)   \
56 {                                                                                                      \
57     JSHandle<JSHClass> result;                                                                         \
58     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();                                     \
59     if (*JSHandle<JSHClass>(env->Get##Type##RootHclassOnHeap()) == (objHclass)) {                      \
60         return JSHandle<JSHClass>(env->Get##Type##RootHclass());                                       \
61     }                                                                                                  \
62     result = JSHClass::Clone((thread), JSHandle<JSHClass>((thread), (objHclass)));                     \
63     result->SetIsOnHeap(false);                                                                        \
64     return result;                                                                                     \
65 }
66 
TYPED_ARRAY_TYPES(GET_NOT_ONHEAP_HCLASS_FROM_TYPE)67 TYPED_ARRAY_TYPES(GET_NOT_ONHEAP_HCLASS_FROM_TYPE)
68 #undef GET_NOT_ONHEAP_HCLASS_FROM_TYPE
69 
70 DataViewType TypedArrayHelper::GetType(const JSHandle<JSTypedArray> &obj)
71 {
72     JSType type = obj->GetJSHClass()->GetObjectType();
73     return GetType(type);
74 }
75 
GetType(JSType type)76 DataViewType TypedArrayHelper::GetType(JSType type)
77 {
78     switch (type) {
79         case JSType::JS_INT8_ARRAY:
80             return DataViewType::INT8;
81         case JSType::JS_UINT8_ARRAY:
82             return DataViewType::UINT8;
83         case JSType::JS_UINT8_CLAMPED_ARRAY:
84             return DataViewType::UINT8_CLAMPED;
85         case JSType::JS_INT16_ARRAY:
86             return DataViewType::INT16;
87         case JSType::JS_UINT16_ARRAY:
88             return DataViewType::UINT16;
89         case JSType::JS_INT32_ARRAY:
90             return DataViewType::INT32;
91         case JSType::JS_UINT32_ARRAY:
92             return DataViewType::UINT32;
93         case JSType::JS_FLOAT32_ARRAY:
94             return DataViewType::FLOAT32;
95         case JSType::JS_FLOAT64_ARRAY:
96             return DataViewType::FLOAT64;
97         case JSType::JS_BIGINT64_ARRAY:
98             return DataViewType::BIGINT64;
99         default:
100             return DataViewType::BIGUINT64;
101     }
102 }
103 
GetElementSize(const JSHandle<JSTypedArray> & obj)104 uint32_t TypedArrayHelper::GetElementSize(const JSHandle<JSTypedArray> &obj)
105 {
106     JSType type = obj->GetJSHClass()->GetObjectType();
107     return GetElementSize(type);
108 }
109 
GetElementSize(JSType type)110 uint32_t TypedArrayHelper::GetElementSize(JSType type)
111 {
112     switch (type) {
113         case JSType::JS_INT8_ARRAY:
114         case JSType::JS_UINT8_ARRAY:
115         case JSType::JS_UINT8_CLAMPED_ARRAY:
116             return ElementSize::ONE;
117         case JSType::JS_INT16_ARRAY:
118         case JSType::JS_UINT16_ARRAY:
119             return ElementSize::TWO;
120         case JSType::JS_INT32_ARRAY:
121         case JSType::JS_UINT32_ARRAY:
122         case JSType::JS_FLOAT32_ARRAY:
123             return ElementSize::FOUR;
124         default:
125             return ElementSize::EIGHT;
126     }
127 }
128 
GetConstructor(JSThread * thread,const JSHandle<JSTaggedValue> & obj)129 JSHandle<JSTaggedValue> TypedArrayHelper::GetConstructor(JSThread *thread, const JSHandle<JSTaggedValue> &obj)
130 {
131     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
132     JSType type = obj->GetTaggedObject()->GetClass()->GetObjectType();
133     switch (type) {
134         case JSType::JS_INT8_ARRAY:
135             return env->GetInt8ArrayFunction();
136         case JSType::JS_UINT8_ARRAY:
137             return env->GetUint8ArrayFunction();
138         case JSType::JS_UINT8_CLAMPED_ARRAY:
139             return env->GetUint8ClampedArrayFunction();
140         case JSType::JS_INT16_ARRAY:
141             return env->GetInt16ArrayFunction();
142         case JSType::JS_UINT16_ARRAY:
143             return env->GetUint16ArrayFunction();
144         case JSType::JS_INT32_ARRAY:
145             return env->GetInt32ArrayFunction();
146         case JSType::JS_UINT32_ARRAY:
147             return env->GetUint32ArrayFunction();
148         case JSType::JS_FLOAT32_ARRAY:
149             return env->GetFloat32ArrayFunction();
150         case JSType::JS_FLOAT64_ARRAY:
151             return env->GetFloat64ArrayFunction();
152         case JSType::JS_BIGINT64_ARRAY:
153             return env->GetBigInt64ArrayFunction();
154         default:
155             return env->GetBigUint64ArrayFunction();
156     }
157 }
158 
GetConstructorFromType(JSThread * thread,const DataViewType arrayType)159 JSHandle<JSFunction> TypedArrayHelper::GetConstructorFromType(JSThread *thread, const DataViewType arrayType)
160 {
161     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
162     switch (arrayType) {
163         case DataViewType::INT8:
164             return JSHandle<JSFunction>(env->GetInt8ArrayFunction());
165         case DataViewType::UINT8:
166             return JSHandle<JSFunction>(env->GetUint8ArrayFunction());
167         case DataViewType::UINT8_CLAMPED:
168             return JSHandle<JSFunction>(env->GetUint8ClampedArrayFunction());
169         case DataViewType::INT16:
170             return JSHandle<JSFunction>(env->GetInt16ArrayFunction());
171         case DataViewType::UINT16:
172             return JSHandle<JSFunction>(env->GetUint16ArrayFunction());
173         case DataViewType::INT32:
174             return JSHandle<JSFunction>(env->GetInt32ArrayFunction());
175         case DataViewType::UINT32:
176             return JSHandle<JSFunction>(env->GetUint32ArrayFunction());
177         case DataViewType::FLOAT32:
178             return JSHandle<JSFunction>(env->GetFloat32ArrayFunction());
179         case DataViewType::FLOAT64:
180             return JSHandle<JSFunction>(env->GetFloat64ArrayFunction());
181         case DataViewType::BIGINT64:
182             return JSHandle<JSFunction>(env->GetBigInt64ArrayFunction());
183         default:
184             break;
185     }
186     return JSHandle<JSFunction>(env->GetBigUint64ArrayFunction());
187 }
188 
GetConstructorNameFromType(JSThread * thread,const DataViewType arrayType)189 JSHandle<JSTaggedValue> TypedArrayHelper::GetConstructorNameFromType(JSThread *thread, const DataViewType arrayType)
190 {
191     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
192     switch (arrayType) {
193         case DataViewType::INT8:
194             return globalConst->GetHandledInt8ArrayString();
195         case DataViewType::UINT8:
196             return globalConst->GetHandledUint8ArrayString();
197         case DataViewType::UINT8_CLAMPED:
198             return globalConst->GetHandledUint8ClampedArrayString();
199         case DataViewType::INT16:
200             return globalConst->GetHandledInt16ArrayString();
201         case DataViewType::UINT16:
202             return globalConst->GetHandledUint16ArrayString();
203         case DataViewType::INT32:
204             return globalConst->GetHandledInt32ArrayString();
205         case DataViewType::UINT32:
206             return globalConst->GetHandledUint32ArrayString();
207         case DataViewType::FLOAT32:
208             return globalConst->GetHandledFloat32ArrayString();
209         case DataViewType::FLOAT64:
210             return globalConst->GetHandledFloat64ArrayString();
211         case DataViewType::BIGINT64:
212             return globalConst->GetHandledBigInt64ArrayString();
213         default:
214             break;
215     }
216     return globalConst->GetHandledBigInt64ArrayString();
217 }
218 
GetOnHeapHclassFromType(JSThread * thread,const JSHandle<JSTypedArray> & obj,const DataViewType arrayType)219 JSHandle<JSHClass> TypedArrayHelper::GetOnHeapHclassFromType(
220     JSThread *thread, const JSHandle<JSTypedArray> &obj, const DataViewType arrayType)
221 {
222     JSHClass* objHclass = JSHandle<TaggedObject>(obj)->GetClass();
223     ASSERT_PRINT(!objHclass->IsOnHeapFromBitField(), "must be not on heap");
224     switch (arrayType) {
225         case DataViewType::INT8:
226             return TypedArrayHelper::GetOnHeapHclassInt8Array(thread, objHclass);
227         case DataViewType::UINT8:
228             return TypedArrayHelper::GetOnHeapHclassUint8Array(thread, objHclass);
229         case DataViewType::UINT8_CLAMPED:
230             return TypedArrayHelper::GetOnHeapHclassUint8ClampedArray(thread, objHclass);
231         case DataViewType::INT16:
232             return TypedArrayHelper::GetOnHeapHclassInt16Array(thread, objHclass);
233         case DataViewType::UINT16:
234             return TypedArrayHelper::GetOnHeapHclassUint16Array(thread, objHclass);
235         case DataViewType::INT32:
236             return TypedArrayHelper::GetOnHeapHclassInt32Array(thread, objHclass);
237         case DataViewType::UINT32:
238             return TypedArrayHelper::GetOnHeapHclassUint32Array(thread, objHclass);
239         case DataViewType::FLOAT32:
240             return TypedArrayHelper::GetOnHeapHclassFloat32Array(thread, objHclass);
241         case DataViewType::FLOAT64:
242             return TypedArrayHelper::GetOnHeapHclassFloat64Array(thread, objHclass);
243         case DataViewType::BIGINT64:
244             return TypedArrayHelper::GetOnHeapHclassBigInt64Array(thread, objHclass);
245         default:
246             break;
247     }
248     return TypedArrayHelper::GetOnHeapHclassBigUint64Array(thread, objHclass);
249 }
250 
GetNotOnHeapHclassFromType(JSThread * thread,const JSHandle<JSTypedArray> & obj,const DataViewType arrayType)251 JSHandle<JSHClass> TypedArrayHelper::GetNotOnHeapHclassFromType(
252     JSThread *thread, const JSHandle<JSTypedArray> &obj, const DataViewType arrayType)
253 {
254     JSHClass* objHclass = JSHandle<TaggedObject>(obj)->GetClass();
255     ASSERT_PRINT(objHclass->IsOnHeapFromBitField(), "must be on heap");
256     switch (arrayType) {
257         case DataViewType::INT8:
258             return TypedArrayHelper::GetNotOnHeapHclassInt8Array(thread, objHclass);
259         case DataViewType::UINT8:
260             return TypedArrayHelper::GetNotOnHeapHclassUint8Array(thread, objHclass);
261         case DataViewType::UINT8_CLAMPED:
262             return TypedArrayHelper::GetNotOnHeapHclassUint8ClampedArray(thread, objHclass);
263         case DataViewType::INT16:
264             return TypedArrayHelper::GetNotOnHeapHclassInt16Array(thread, objHclass);
265         case DataViewType::UINT16:
266             return TypedArrayHelper::GetNotOnHeapHclassUint16Array(thread, objHclass);
267         case DataViewType::INT32:
268             return TypedArrayHelper::GetNotOnHeapHclassInt32Array(thread, objHclass);
269         case DataViewType::UINT32:
270             return TypedArrayHelper::GetOnHeapHclassUint32Array(thread, objHclass);
271         case DataViewType::FLOAT32:
272             return TypedArrayHelper::GetNotOnHeapHclassFloat32Array(thread, objHclass);
273         case DataViewType::FLOAT64:
274             return TypedArrayHelper::GetNotOnHeapHclassFloat64Array(thread, objHclass);
275         case DataViewType::BIGINT64:
276             return TypedArrayHelper::GetNotOnHeapHclassBigInt64Array(thread, objHclass);
277         default:
278             break;
279     }
280     return TypedArrayHelper::GetNotOnHeapHclassBigUint64Array(thread, objHclass);
281 }
282 
GetSizeFromType(const DataViewType arrayType)283 uint32_t TypedArrayHelper::GetSizeFromType(const DataViewType arrayType)
284 {
285     if (arrayType == DataViewType::INT8 ||
286         arrayType == DataViewType::UINT8 ||
287         arrayType == DataViewType::UINT8_CLAMPED) {
288         return ElementSize::ONE;
289     }
290 
291     if (arrayType == DataViewType::INT16 ||
292         arrayType == DataViewType::UINT16) {
293         return ElementSize::TWO;
294     }
295 
296     if (arrayType == DataViewType::FLOAT32 ||
297         arrayType == DataViewType::UINT32 ||
298         arrayType == DataViewType::INT32) {
299         return ElementSize::FOUR;
300     }
301 
302     return ElementSize::EIGHT;
303 }
304 
IsAccessorHasChanged(const JSHandle<JSTaggedValue> & obj)305 bool TypedArrayHelper::IsAccessorHasChanged(const JSHandle<JSTaggedValue> &obj)
306 {
307     if (obj->IsHeapObject()) {
308         JSTaggedValue markerValue = obj->GetTaggedObject()->GetClass()->GetProtoChangeMarker();
309         if (markerValue.IsProtoChangeMarker()) {
310             return ProtoChangeMarker::Cast(markerValue.GetTaggedObject())->GetAccessorHasChanged();
311         }
312     }
313     return false;
314 }
315 }  // namespace panda::ecmascript::base
316 #endif  // ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H
317