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