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