• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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