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_BUILTINS_BUILTINS_SENDABLE_ARRAYBUFFER_H
17 #define ECMASCRIPT_BUILTINS_BUILTINS_SENDABLE_ARRAYBUFFER_H
18 
19 #include "ecmascript/base/builtins_base.h"
20 #include "ecmascript/builtins/builtins_arraybuffer.h"
21 #include "ecmascript/base/number_helper.h"
22 #include "ecmascript/js_dataview.h"
23 #include "ecmascript/js_typed_array.h"
24 
25 // List of functions in ArrayBuffer, excluding the '@@' properties.
26 // V(name, func, length, stubIndex)
27 // where BuiltinsArrayBuffer::func refers to the native implementation of ArrayBuffer[name].
28 //       kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
29 #define BUILTIN_ARRAY_BUFFER_FUNCTIONS(V)                                           \
30     /* ArrayBuffer.isView ( arg ) */                                                \
31     V("isView", IsView, 1, ArrayBufferIsView)
32 
33 namespace panda::ecmascript::builtins {
34 using DataViewType = ecmascript::DataViewType;
35 using BuiltinFunctionEntry = base::BuiltinFunctionEntry;
36 
37 class BuiltinsSendableArrayBuffer : public BuiltinsArrayBuffer {
38 public:
39     // 24.1.2.1 ArrayBuffer(length)
40     static JSTaggedValue ArrayBufferConstructor(EcmaRuntimeCallInfo *argv);
41     // 24.1.3.1 ArrayBuffer.isView(arg)
42     static JSTaggedValue IsView(EcmaRuntimeCallInfo *argv);
43     // 24.1.3.3 get ArrayBuffer[@@species]
44     static JSTaggedValue Species(EcmaRuntimeCallInfo *argv);
45     // 24.1.4.1 get ArrayBuffer.prototype.byteLength
46     static JSTaggedValue GetByteLength(EcmaRuntimeCallInfo *argv);
47     // 24.1.4.3 ArrayBuffer.prototype.slice()
48     static JSTaggedValue Slice(EcmaRuntimeCallInfo *argv);
49     // 24.1.1.2 IsDetachedBuffer(arrayBuffer)
50 
51     static bool IsDetachedBuffer(JSTaggedValue arrayBuffer);
52     // 24.1.1.4 CloneArrayBuffer( srcBuffer, srcByteOffset [, cloneConstructor] )
53     static JSTaggedValue CloneArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &srcBuffer,
54                                           uint32_t srcByteOffset, JSHandle<JSTaggedValue> constructor);
55     // 24.1.1.1 AllocateArrayBuffer(constructor, byteLength)
56     static JSTaggedValue AllocateSendableArrayBuffer(
57         JSThread *thread, const JSHandle<JSTaggedValue> &newTarget, uint64_t byteLength);
58 
59     // Excluding the '@@' internal properties
GetArrayBufferFunctions()60     static Span<const base::BuiltinFunctionEntry> GetArrayBufferFunctions()
61     {
62         return Span<const base::BuiltinFunctionEntry>(ARRAY_BUFFER_FUNCTIONS);
63     }
64 
GetNumPrototypeInlinedProperties()65     static size_t GetNumPrototypeInlinedProperties()
66     {
67         // 3 : 3 more inline properties in Set.prototype
68         //  (1) ArrayBuffer.prototype.slice
69         //  (2) get ArrayBuffer.prototype.byteLength
70         //  (3) ArrayBuffer.prototype [ @@toStringTag ]
71         return 3;
72     }
73 
GetPrototypeProperties()74     static Span<const std::pair<std::string_view, bool>> GetPrototypeProperties()
75     {
76         return Span<const std::pair<std::string_view, bool>>(ARRAYBUFFER_PROTOTYPE_PROPERTIES);
77     }
78 
GetFunctionProperties()79     static Span<const std::pair<std::string_view, bool>> GetFunctionProperties()
80     {
81         return Span<const std::pair<std::string_view, bool>>(ARRAYBUFFER_FUNCTION_PROPERTIES);
82     }
83 
84     static void *GetDataPointFromBuffer(JSTaggedValue arrBuf, uint32_t byteOffset = 0);
85 private:
86 #define BUILTIN_ARRAY_BUFFER_ENTRY(name, func, length, id) \
87     BuiltinFunctionEntry::Create(name, BuiltinsSendableArrayBuffer::func, length, kungfu::BuiltinsStubCSigns::id),
88 
89     static constexpr std::array ARRAY_BUFFER_FUNCTIONS = {
90         BUILTIN_ARRAY_BUFFER_FUNCTIONS(BUILTIN_ARRAY_BUFFER_ENTRY)
91     };
92 #undef BUILTIN_ARRAY_BUFFER_ENTRY
93 
94 #define ARRAYBUFFER_PROPERTIES_PAIR(name, func, length, id) \
95     std::pair<std::string_view, bool>(name, false),
96 
97     static constexpr std::array ARRAYBUFFER_PROTOTYPE_PROPERTIES = {
98         std::pair<std::string_view, bool>("slice", false),
99         std::pair<std::string_view, bool>("byteLength", true),
100         std::pair<std::string_view, bool>("[Symbol.toStringTag]", false),
101     };
102 
103     static constexpr std::array ARRAYBUFFER_FUNCTION_PROPERTIES = {
104         std::pair<std::string_view, bool>("length", false),
105         std::pair<std::string_view, bool>("name", false),
106         std::pair<std::string_view, bool>("prototype", false),
107         std::pair<std::string_view, bool>("[Symbol.species]", true),
108         BUILTIN_ARRAY_BUFFER_FUNCTIONS(ARRAYBUFFER_PROPERTIES_PAIR)
109     };
110 #undef ARRAYBUFFER_PROPERTIES_PAIR
111 };
112 }  // namespace panda::ecmascript::builtins
113 
114 #endif  // ECMASCRIPT_BUILTINS_BUILTINS_SENDABLE_ARRAYBUFFER_H
115