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_JSPROXY_H
17#define ECMASCRIPT_JSPROXY_H
18
19#include "ecmascript/ecma_runtime_call_info.h"
20#include "ecmascript/js_object.h"
21#include "ecmascript/tagged_array.h"
22
23namespace panda::ecmascript {
24class JSProxy final : public ECMAObject {
25public:
26    CAST_CHECK(JSProxy, IsJSProxy);
27
28    // ES6 9.5.15 ProxyCreate(target, handler)
29    static JSHandle<JSProxy> ProxyCreate(JSThread *thread, const JSHandle<JSTaggedValue> &target,
30                                         const JSHandle<JSTaggedValue> &handler);
31    // ES6 9.5.1 [[GetPrototypeOf]] ( )
32    static JSTaggedValue GetPrototype(JSThread *thread, const JSHandle<JSProxy> &proxy);
33    // ES6 9.5.2 [[SetPrototypeOf]] (V)
34    static bool SetPrototype(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &proto);
35    // ES6 9.5.3 [[IsExtensible]] ( )
36    static bool IsExtensible(JSThread *thread, const JSHandle<JSProxy> &proxy);
37    // ES6 9.5.4 [[PreventExtensions]] ( )
38    static bool PreventExtensions(JSThread *thread, const JSHandle<JSProxy> &proxy);
39    // ES6 9.5.5 [[GetOwnProperty]] (P)
40    static bool GetOwnProperty(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &key,
41                               PropertyDescriptor &desc);
42    // ES6 9.5.6 [[DefineOwnProperty]] (P, Desc)
43    static bool DefineOwnProperty(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &key,
44                                  const PropertyDescriptor &desc);
45    // ES6 9.5.7 [[HasProperty]] (P)
46    static bool HasProperty(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &key);
47    // ES6 9.5.8 [[Get]] (P, Receiver)
48    static inline OperationResult GetProperty(JSThread *thread, const JSHandle<JSProxy> &proxy,
49                                              const JSHandle<JSTaggedValue> &key)
50    {
51        return GetProperty(thread, proxy, key, JSHandle<JSTaggedValue>::Cast(proxy));
52    }
53    static OperationResult GetProperty(JSThread *thread, const JSHandle<JSProxy> &proxy,
54                                       const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &receiver);
55    // ES6 9.5.9 [[Set]] ( P, V, Receiver)
56    static inline bool SetProperty(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &key,
57                                   const JSHandle<JSTaggedValue> &value, bool mayThrow = false)
58    {
59        return SetProperty(thread, proxy, key, value, JSHandle<JSTaggedValue>::Cast(proxy), mayThrow);
60    }
61    static bool SetProperty(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &key,
62                            const JSHandle<JSTaggedValue> &value, const JSHandle<JSTaggedValue> &receiver,
63                            bool mayThrow = false);
64    // ES6 9.5.10 [[Delete]] (P)
65    static bool DeleteProperty(JSThread *thread, const JSHandle<JSProxy> &proxy, const JSHandle<JSTaggedValue> &key);
66
67    // ES6 9.5.12 [[OwnPropertyKeys]] ()
68    static JSHandle<TaggedArray> OwnPropertyKeys(JSThread *thread, const JSHandle<JSProxy> &proxy);
69
70    static JSHandle<TaggedArray> GetAllPropertyKeys(JSThread *thread, const JSHandle<JSProxy> &proxy, uint32_t filter);
71
72    void SetCallable(bool callable) const
73    {
74        GetClass()->SetCallable(callable);
75    }
76
77    void SetConstructor(bool constructor) const
78    {
79        GetClass()->SetConstructor(constructor);
80    }
81
82    JSHandle<JSTaggedValue> GetSourceTarget(JSThread *thread) const;
83
84    // ES6 9.5.13 [[Call]] (thisArgument, argumentsList)
85    static JSTaggedValue CallInternal(EcmaRuntimeCallInfo *info);
86    // ES6 9.5.14 [[Construct]] ( argumentsList, newTarget)
87    static JSTaggedValue ConstructInternal(EcmaRuntimeCallInfo *info);
88
89    bool PUBLIC_API IsArray(JSThread *thread) const;
90
91    static constexpr size_t TARGET_OFFSET = ECMAObject::SIZE;
92    ACCESSORS(Target, TARGET_OFFSET, HANDLER_OFFSET)
93    ACCESSORS(Handler, HANDLER_OFFSET, METHOD_OFFSET)
94    ACCESSORS(Method, METHOD_OFFSET, PRIVATE_FIELD_OFFSET)
95    ACCESSORS(PrivateField, PRIVATE_FIELD_OFFSET, BIT_FIELD_OFFSET)
96    ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET)
97    DEFINE_ALIGN_SIZE(LAST_OFFSET);
98
99    // define BitField
100    static constexpr size_t IS_REVOKED_BITS = 1;
101    FIRST_BIT_FIELD(BitField, IsRevoked, bool, IS_REVOKED_BITS)
102
103    DECL_DUMP()
104
105    DECL_VISIT_OBJECT(TARGET_OFFSET, BIT_FIELD_OFFSET)
106};
107}  // namespace panda::ecmascript
108
109#endif  // ECMASCRIPT_JSPROXY_H
110