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
33namespace panda::ecmascript::builtins {
34using DataViewType = ecmascript::DataViewType;
35using BuiltinFunctionEntry = base::BuiltinFunctionEntry;
36
37class BuiltinsSendableArrayBuffer : public BuiltinsArrayBuffer {
38public:
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
60    static Span<const base::BuiltinFunctionEntry> GetArrayBufferFunctions()
61    {
62        return Span<const base::BuiltinFunctionEntry>(ARRAY_BUFFER_FUNCTIONS);
63    }
64
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
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
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);
85private:
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