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