1 /*
2 * Copyright (c) 2023 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 #include "ecmascript/builtins/builtins_lazy_callback.h"
17
18 #include "ecmascript/builtins/builtins.h"
19 #include "ecmascript/global_dictionary-inl.h"
20 #include "ecmascript/tagged_dictionary.h"
21 #include "ecmascript/ecma_macros.h"
22
23 namespace panda::ecmascript::builtins {
Date(JSThread * thread,const JSHandle<JSObject> & obj)24 JSTaggedValue BuiltinsLazyCallback::Date(JSThread *thread, const JSHandle<JSObject> &obj)
25 {
26 [[maybe_unused]] EcmaHandleScope scope(thread);
27 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
28 EcmaVM *vm = thread->GetEcmaVM();
29 ObjectFactory *factory = vm->GetFactory();
30 auto env = vm->GetGlobalEnv();
31 ResetLazyInternalAttr(thread, obj, "Date");
32 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
33 Builtins builtin(thread, factory, vm);
34 builtin.InitializeDate(env, objFuncClass);
35 return env->GetDateFunction().GetTaggedValue();
36 }
37
Set(JSThread * thread,const JSHandle<JSObject> & obj)38 JSTaggedValue BuiltinsLazyCallback::Set(JSThread *thread, const JSHandle<JSObject> &obj)
39 {
40 [[maybe_unused]] EcmaHandleScope scope(thread);
41 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
42 EcmaVM *vm = thread->GetEcmaVM();
43 ObjectFactory *factory = vm->GetFactory();
44 auto env = vm->GetGlobalEnv();
45 ResetLazyInternalAttr(thread, obj, "Set");
46 Builtins builtin(thread, factory, vm);
47 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
48 builtin.InitializeSet(env, objFuncClass);
49 return env->GetBuiltinsSetFunction().GetTaggedValue();
50 }
51
Map(JSThread * thread,const JSHandle<JSObject> & obj)52 JSTaggedValue BuiltinsLazyCallback::Map(JSThread *thread, const JSHandle<JSObject> &obj)
53 {
54 [[maybe_unused]] EcmaHandleScope scope(thread);
55 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
56 EcmaVM *vm = thread->GetEcmaVM();
57 ObjectFactory *factory = vm->GetFactory();
58 auto env = vm->GetGlobalEnv();
59 ResetLazyInternalAttr(thread, obj, "Map");
60 Builtins builtin(thread, factory, vm);
61 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
62 builtin.InitializeMap(env, objFuncClass);
63 return env->GetBuiltinsMapFunction().GetTaggedValue();
64 }
65
WeakMap(JSThread * thread,const JSHandle<JSObject> & obj)66 JSTaggedValue BuiltinsLazyCallback::WeakMap(JSThread *thread, const JSHandle<JSObject> &obj)
67 {
68 [[maybe_unused]] EcmaHandleScope scope(thread);
69 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
70 EcmaVM *vm = thread->GetEcmaVM();
71 ObjectFactory *factory = vm->GetFactory();
72 auto env = vm->GetGlobalEnv();
73 ResetLazyInternalAttr(thread, obj, "WeakMap");
74 Builtins builtin(thread, factory, vm);
75 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
76 builtin.InitializeWeakMap(env, objFuncClass);
77 return env->GetBuiltinsWeakMapFunction().GetTaggedValue();
78 }
79
WeakSet(JSThread * thread,const JSHandle<JSObject> & obj)80 JSTaggedValue BuiltinsLazyCallback::WeakSet(JSThread *thread, const JSHandle<JSObject> &obj)
81 {
82 [[maybe_unused]] EcmaHandleScope scope(thread);
83 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
84 EcmaVM *vm = thread->GetEcmaVM();
85 ObjectFactory *factory = vm->GetFactory();
86 auto env = vm->GetGlobalEnv();
87 ResetLazyInternalAttr(thread, obj, "WeakSet");
88 Builtins builtin(thread, factory, vm);
89 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
90 builtin.InitializeWeakSet(env, objFuncClass);
91 return env->GetBuiltinsWeakSetFunction().GetTaggedValue();
92 }
93
WeakRef(JSThread * thread,const JSHandle<JSObject> & obj)94 JSTaggedValue BuiltinsLazyCallback::WeakRef(JSThread *thread, const JSHandle<JSObject> &obj)
95 {
96 [[maybe_unused]] EcmaHandleScope scope(thread);
97 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
98 EcmaVM *vm = thread->GetEcmaVM();
99 ObjectFactory *factory = vm->GetFactory();
100 auto env = vm->GetGlobalEnv();
101 ResetLazyInternalAttr(thread, obj, "WeakRef");
102 Builtins builtin(thread, factory, vm);
103 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
104 builtin.InitializeWeakRef(env, objFuncClass);
105 return env->GetBuiltinsWeakRefFunction().GetTaggedValue();
106 }
107
FinalizationRegistry(JSThread * thread,const JSHandle<JSObject> & obj)108 JSTaggedValue BuiltinsLazyCallback::FinalizationRegistry(JSThread *thread, const JSHandle<JSObject> &obj)
109 {
110 [[maybe_unused]] EcmaHandleScope scope(thread);
111 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
112 EcmaVM *vm = thread->GetEcmaVM();
113 ObjectFactory *factory = vm->GetFactory();
114 auto env = vm->GetGlobalEnv();
115 ResetLazyInternalAttr(thread, obj, "FinalizationRegistry");
116 Builtins builtin(thread, factory, vm);
117 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
118 builtin.InitializeFinalizationRegistry(env, objFuncClass);
119 return env->GetBuiltinsFinalizationRegistryFunction().GetTaggedValue();
120 }
121
TypedArray(JSThread * thread,const JSHandle<JSObject> & obj)122 JSTaggedValue BuiltinsLazyCallback::TypedArray(JSThread *thread, const JSHandle<JSObject> &obj)
123 {
124 [[maybe_unused]] EcmaHandleScope scope(thread);
125 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
126 EcmaVM *vm = thread->GetEcmaVM();
127 ObjectFactory *factory = vm->GetFactory();
128 auto env = vm->GetGlobalEnv();
129 ResetLazyInternalAttr(thread, obj, "TypedArray");
130
131 #define RESET_TYPED_ARRAY_INTERNAL_ATTR(type) \
132 ResetLazyInternalAttr(thread, obj, #type);
133
134 ITERATE_TYPED_ARRAY(RESET_TYPED_ARRAY_INTERNAL_ATTR)
135 #undef RESET_TYPED_ARRAY_INTERNAL_ATTR
136 Builtins builtin(thread, factory, vm);
137 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
138 builtin.InitializeTypedArray(env, objFuncClass);
139 return env->GetTypedArrayFunction().GetTaggedValue();
140 }
141
142 #define TYPED_ARRAY_CALLBACK(type) \
143 JSTaggedValue BuiltinsLazyCallback::type(JSThread *thread, const JSHandle<JSObject> &obj) \
144 { \
145 [[maybe_unused]] EcmaHandleScope scope(thread); \
146 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__; \
147 EcmaVM *vm = thread->GetEcmaVM(); \
148 auto env = vm->GetGlobalEnv(); \
149 TypedArray(thread, obj); \
150 return env->Get##type##Function().GetTaggedValue(); \
151 }
152
ITERATE_TYPED_ARRAY(TYPED_ARRAY_CALLBACK)153 ITERATE_TYPED_ARRAY(TYPED_ARRAY_CALLBACK)
154 #undef TYPED_ARRAY_CALLBACK
155
156 JSTaggedValue BuiltinsLazyCallback::ArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj)
157 {
158 [[maybe_unused]] EcmaHandleScope scope(thread);
159 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
160 EcmaVM *vm = thread->GetEcmaVM();
161 ObjectFactory *factory = vm->GetFactory();
162 auto env = vm->GetGlobalEnv();
163 ResetLazyInternalAttr(thread, obj, "ArrayBuffer");
164 Builtins builtin(thread, factory, vm);
165 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
166 builtin.InitializeArrayBuffer(env, objFuncClass);
167 return env->GetArrayBufferFunction().GetTaggedValue();
168 }
169
DataView(JSThread * thread,const JSHandle<JSObject> & obj)170 JSTaggedValue BuiltinsLazyCallback::DataView(JSThread *thread, const JSHandle<JSObject> &obj)
171 {
172 [[maybe_unused]] EcmaHandleScope scope(thread);
173 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
174 EcmaVM *vm = thread->GetEcmaVM();
175 ObjectFactory *factory = vm->GetFactory();
176 auto env = vm->GetGlobalEnv();
177 ResetLazyInternalAttr(thread, obj, "DataView");
178 Builtins builtin(thread, factory, vm);
179 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
180 builtin.InitializeDataView(env, objFuncClass);
181 return env->GetDataViewFunction().GetTaggedValue();
182 }
183
SharedArrayBuffer(JSThread * thread,const JSHandle<JSObject> & obj)184 JSTaggedValue BuiltinsLazyCallback::SharedArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj)
185 {
186 [[maybe_unused]] EcmaHandleScope scope(thread);
187 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
188 EcmaVM *vm = thread->GetEcmaVM();
189 ObjectFactory *factory = vm->GetFactory();
190 auto env = vm->GetGlobalEnv();
191 ResetLazyInternalAttr(thread, obj, "SharedArrayBuffer");
192 Builtins builtin(thread, factory, vm);
193 JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
194 builtin.InitializeSharedArrayBuffer(env, objFuncClass);
195 return env->GetSharedArrayBufferFunction().GetTaggedValue();
196 }
197
198 #ifdef ARK_SUPPORT_INTL
199 #define INTL_CALLBACK(type) \
200 JSTaggedValue BuiltinsLazyCallback::type(JSThread *thread, const JSHandle<JSObject> &obj) \
201 { \
202 [[maybe_unused]] EcmaHandleScope scope(thread); \
203 LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__; \
204 EcmaVM *vm = thread->GetEcmaVM(); \
205 auto env = vm->GetGlobalEnv(); \
206 ObjectFactory *factory = vm->GetFactory(); \
207 ResetLazyInternalAttr(thread, obj, #type); \
208 Builtins builtin(thread, factory, vm); \
209 builtin.Initialize##type(env); \
210 return env->Get##type##Function().GetTaggedValue(); \
211 }
212
ITERATE_INTL(INTL_CALLBACK)213 ITERATE_INTL(INTL_CALLBACK)
214 #undef INTL_CALLBACK
215 #endif
216
217 void BuiltinsLazyCallback::ResetLazyInternalAttr(JSThread *thread, const JSHandle<JSObject> &object,
218 const char *name)
219 {
220 JSHClass *hclass = object->GetClass();
221 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
222 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(name));
223 if (LIKELY(!hclass->IsDictionaryMode())) {
224 LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
225 uint32_t propsNumber = hclass->NumberOfProps();
226 int entry = layoutInfo->FindElementWithCache(thread, hclass, key.GetTaggedValue(), propsNumber);
227 if (entry != -1) {
228 PropertyAttributes attr(layoutInfo->GetAttr(entry));
229 attr.SetIsAccessor(false);
230 layoutInfo->SetNormalAttr(thread, entry, attr);
231 }
232 } else {
233 TaggedArray *array = TaggedArray::Cast(object->GetProperties().GetTaggedObject());
234 ASSERT(array->IsDictionaryMode());
235 NameDictionary *dict = NameDictionary::Cast(array);
236 int entry = dict->FindEntry(key.GetTaggedValue());
237 if (entry != -1) {
238 auto attr = dict->GetAttributes(entry);
239 attr.SetIsAccessor(false);
240 dict->SetAttributes(thread, entry, attr);
241 }
242 }
243 }
244 } // namespace panda::ecmascript::builtins
245