14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_lazy_callback.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins.h"
194514f5e3Sopenharmony_ci#include "ecmascript/layout_info-inl.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins {
224514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::Date(JSThread *thread, const JSHandle<JSObject> &obj)
234514f5e3Sopenharmony_ci{
244514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
254514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
264514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
274514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
284514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
294514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "Date");
304514f5e3Sopenharmony_ci
314514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFuncPrototypeVal = env->GetObjectFunctionPrototype();
324514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
334514f5e3Sopenharmony_ci    builtin.InitializeDate(env, objFuncPrototypeVal);
344514f5e3Sopenharmony_ci    return env->GetDateFunction().GetTaggedValue();
354514f5e3Sopenharmony_ci}
364514f5e3Sopenharmony_ci
374514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::Set(JSThread *thread, const JSHandle<JSObject> &obj)
384514f5e3Sopenharmony_ci{
394514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
404514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
414514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
424514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
434514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
444514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "Set");
454514f5e3Sopenharmony_ci
464514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
474514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFuncPrototypeVal = env->GetObjectFunctionPrototype();
484514f5e3Sopenharmony_ci    builtin.InitializeSet(env, objFuncPrototypeVal);
494514f5e3Sopenharmony_ci    return env->GetBuiltinsSetFunction().GetTaggedValue();
504514f5e3Sopenharmony_ci}
514514f5e3Sopenharmony_ci
524514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::Map(JSThread *thread, const JSHandle<JSObject> &obj)
534514f5e3Sopenharmony_ci{
544514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
554514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
564514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
574514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
584514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
594514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "Map");
604514f5e3Sopenharmony_ci
614514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
624514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFuncPrototypeVal = env->GetObjectFunctionPrototype();
634514f5e3Sopenharmony_ci    builtin.InitializeMap(env, objFuncPrototypeVal);
644514f5e3Sopenharmony_ci    return env->GetBuiltinsMapFunction().GetTaggedValue();
654514f5e3Sopenharmony_ci}
664514f5e3Sopenharmony_ci
674514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::WeakMap(JSThread *thread, const JSHandle<JSObject> &obj)
684514f5e3Sopenharmony_ci{
694514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
704514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
714514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
724514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
734514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
744514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "WeakMap");
754514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
764514f5e3Sopenharmony_ci    JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
774514f5e3Sopenharmony_ci    builtin.InitializeWeakMap(env, objFuncClass);
784514f5e3Sopenharmony_ci    return env->GetBuiltinsWeakMapFunction().GetTaggedValue();
794514f5e3Sopenharmony_ci}
804514f5e3Sopenharmony_ci
814514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::WeakSet(JSThread *thread, const JSHandle<JSObject> &obj)
824514f5e3Sopenharmony_ci{
834514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
844514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
854514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
864514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
874514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
884514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "WeakSet");
894514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
904514f5e3Sopenharmony_ci    JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
914514f5e3Sopenharmony_ci    builtin.InitializeWeakSet(env, objFuncClass);
924514f5e3Sopenharmony_ci    return env->GetBuiltinsWeakSetFunction().GetTaggedValue();
934514f5e3Sopenharmony_ci}
944514f5e3Sopenharmony_ci
954514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::WeakRef(JSThread *thread, const JSHandle<JSObject> &obj)
964514f5e3Sopenharmony_ci{
974514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
984514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
994514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
1004514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
1014514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
1024514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "WeakRef");
1034514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
1044514f5e3Sopenharmony_ci    JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
1054514f5e3Sopenharmony_ci    builtin.InitializeWeakRef(env, objFuncClass);
1064514f5e3Sopenharmony_ci    return env->GetBuiltinsWeakRefFunction().GetTaggedValue();
1074514f5e3Sopenharmony_ci}
1084514f5e3Sopenharmony_ci
1094514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::FinalizationRegistry(JSThread *thread, const JSHandle<JSObject> &obj)
1104514f5e3Sopenharmony_ci{
1114514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
1124514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
1134514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
1144514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
1154514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
1164514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "FinalizationRegistry");
1174514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
1184514f5e3Sopenharmony_ci    JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
1194514f5e3Sopenharmony_ci    builtin.InitializeFinalizationRegistry(env, objFuncClass);
1204514f5e3Sopenharmony_ci    return env->GetBuiltinsFinalizationRegistryFunction().GetTaggedValue();
1214514f5e3Sopenharmony_ci}
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::TypedArray(JSThread *thread, const JSHandle<JSObject> &obj)
1244514f5e3Sopenharmony_ci{
1254514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
1264514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
1274514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
1284514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
1294514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
1304514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "TypedArray");
1314514f5e3Sopenharmony_ci
1324514f5e3Sopenharmony_ci#define RESET_TYPED_ARRAY_INTERNAL_ATTR(type)                                                             \
1334514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, #type);
1344514f5e3Sopenharmony_ci
1354514f5e3Sopenharmony_ciITERATE_TYPED_ARRAY(RESET_TYPED_ARRAY_INTERNAL_ATTR)
1364514f5e3Sopenharmony_ci#undef RESET_TYPED_ARRAY_INTERNAL_ATTR
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
1394514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFuncPrototypeVal = env->GetObjectFunctionPrototype();
1404514f5e3Sopenharmony_ci    builtin.InitializeTypedArray(env, objFuncPrototypeVal);
1414514f5e3Sopenharmony_ci    return env->GetTypedArrayFunction().GetTaggedValue();
1424514f5e3Sopenharmony_ci}
1434514f5e3Sopenharmony_ci
1444514f5e3Sopenharmony_ci#define TYPED_ARRAY_CALLBACK(type)                                                                       \
1454514f5e3Sopenharmony_ci    JSTaggedValue BuiltinsLazyCallback::type(JSThread *thread, const JSHandle<JSObject> &obj)            \
1464514f5e3Sopenharmony_ci    {                                                                                                    \
1474514f5e3Sopenharmony_ci        [[maybe_unused]] EcmaHandleScope scope(thread);                                                  \
1484514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;                                         \
1494514f5e3Sopenharmony_ci        EcmaVM *vm = thread->GetEcmaVM();                                                                \
1504514f5e3Sopenharmony_ci        auto env = vm->GetGlobalEnv();                                                                   \
1514514f5e3Sopenharmony_ci        TypedArray(thread, obj);                                                                         \
1524514f5e3Sopenharmony_ci        return env->Get##type##Function().GetTaggedValue();                                              \
1534514f5e3Sopenharmony_ci    }
1544514f5e3Sopenharmony_ci
1554514f5e3Sopenharmony_ciITERATE_TYPED_ARRAY(TYPED_ARRAY_CALLBACK)
1564514f5e3Sopenharmony_ci#undef TYPED_ARRAY_CALLBACK
1574514f5e3Sopenharmony_ci
1584514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::ArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj)
1594514f5e3Sopenharmony_ci{
1604514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
1614514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
1624514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
1634514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
1644514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
1654514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "ArrayBuffer");
1664514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
1674514f5e3Sopenharmony_ci    JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
1684514f5e3Sopenharmony_ci    builtin.InitializeArrayBuffer(env, objFuncClass);
1694514f5e3Sopenharmony_ci    return env->GetArrayBufferFunction().GetTaggedValue();
1704514f5e3Sopenharmony_ci}
1714514f5e3Sopenharmony_ci
1724514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::DataView(JSThread *thread, const JSHandle<JSObject> &obj)
1734514f5e3Sopenharmony_ci{
1744514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
1754514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
1764514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
1774514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
1784514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
1794514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "DataView");
1804514f5e3Sopenharmony_ci
1814514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
1824514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFuncPrototypeVal = env->GetObjectFunctionPrototype();
1834514f5e3Sopenharmony_ci    builtin.InitializeDataView(env, objFuncPrototypeVal);
1844514f5e3Sopenharmony_ci    return env->GetDataViewFunction().GetTaggedValue();
1854514f5e3Sopenharmony_ci}
1864514f5e3Sopenharmony_ci
1874514f5e3Sopenharmony_ciJSTaggedValue BuiltinsLazyCallback::SharedArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj)
1884514f5e3Sopenharmony_ci{
1894514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope scope(thread);
1904514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
1914514f5e3Sopenharmony_ci    EcmaVM *vm = thread->GetEcmaVM();
1924514f5e3Sopenharmony_ci    ObjectFactory *factory = vm->GetFactory();
1934514f5e3Sopenharmony_ci    auto env = vm->GetGlobalEnv();
1944514f5e3Sopenharmony_ci    ResetLazyInternalAttr(thread, obj, "SharedArrayBuffer");
1954514f5e3Sopenharmony_ci    Builtins builtin(thread, factory, vm);
1964514f5e3Sopenharmony_ci    JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
1974514f5e3Sopenharmony_ci    builtin.InitializeSharedArrayBuffer(env, objFuncClass);
1984514f5e3Sopenharmony_ci    return env->GetSharedArrayBufferFunction().GetTaggedValue();
1994514f5e3Sopenharmony_ci}
2004514f5e3Sopenharmony_ci
2014514f5e3Sopenharmony_ci#ifdef ARK_SUPPORT_INTL
2024514f5e3Sopenharmony_ci#define INTL_CALLBACK(type)                                                                       \
2034514f5e3Sopenharmony_ci    JSTaggedValue BuiltinsLazyCallback::type(JSThread *thread, const JSHandle<JSObject> &obj)     \
2044514f5e3Sopenharmony_ci    {                                                                                             \
2054514f5e3Sopenharmony_ci        [[maybe_unused]] EcmaHandleScope scope(thread);                                           \
2064514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;                                  \
2074514f5e3Sopenharmony_ci        EcmaVM *vm = thread->GetEcmaVM();                                                         \
2084514f5e3Sopenharmony_ci        auto env = vm->GetGlobalEnv();                                                            \
2094514f5e3Sopenharmony_ci        ObjectFactory *factory = vm->GetFactory();                                                \
2104514f5e3Sopenharmony_ci        ResetLazyInternalAttr(thread, obj, #type);                                                \
2114514f5e3Sopenharmony_ci        Builtins builtin(thread, factory, vm);                                                    \
2124514f5e3Sopenharmony_ci        builtin.Initialize##type(env);                                                            \
2134514f5e3Sopenharmony_ci        return env->Get##type##Function().GetTaggedValue();                                       \
2144514f5e3Sopenharmony_ci    }
2154514f5e3Sopenharmony_ci
2164514f5e3Sopenharmony_ciITERATE_INTL(INTL_CALLBACK)
2174514f5e3Sopenharmony_ci#undef INTL_CALLBACK
2184514f5e3Sopenharmony_ci#endif
2194514f5e3Sopenharmony_ci
2204514f5e3Sopenharmony_civoid BuiltinsLazyCallback::ResetLazyInternalAttr(JSThread *thread, const JSHandle<JSObject> &object,
2214514f5e3Sopenharmony_ci    const char *name)
2224514f5e3Sopenharmony_ci{
2234514f5e3Sopenharmony_ci    JSHClass *hclass = object->GetClass();
2244514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2254514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key(factory->NewFromUtf8ReadOnly(name));
2264514f5e3Sopenharmony_ci    if (LIKELY(!hclass->IsDictionaryMode())) {
2274514f5e3Sopenharmony_ci        LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
2284514f5e3Sopenharmony_ci        uint32_t propsNumber = hclass->NumberOfProps();
2294514f5e3Sopenharmony_ci        int entry = layoutInfo->FindElementWithCache(thread, hclass, key.GetTaggedValue(), propsNumber);
2304514f5e3Sopenharmony_ci        if (entry != -1) {
2314514f5e3Sopenharmony_ci            PropertyAttributes attr(layoutInfo->GetAttr(entry));
2324514f5e3Sopenharmony_ci            attr.SetIsAccessor(false);
2334514f5e3Sopenharmony_ci            layoutInfo->SetNormalAttr(thread, entry, attr);
2344514f5e3Sopenharmony_ci        }
2354514f5e3Sopenharmony_ci    } else {
2364514f5e3Sopenharmony_ci        TaggedArray *array = TaggedArray::Cast(object->GetProperties().GetTaggedObject());
2374514f5e3Sopenharmony_ci        ASSERT(array->IsDictionaryMode());
2384514f5e3Sopenharmony_ci        NameDictionary *dict = NameDictionary::Cast(array);
2394514f5e3Sopenharmony_ci        int entry = dict->FindEntry(key.GetTaggedValue());
2404514f5e3Sopenharmony_ci        if (entry != -1) {
2414514f5e3Sopenharmony_ci            auto attr = dict->GetAttributes(entry);
2424514f5e3Sopenharmony_ci            attr.SetIsAccessor(false);
2434514f5e3Sopenharmony_ci            dict->SetAttributes(thread, entry, attr);
2444514f5e3Sopenharmony_ci        }
2454514f5e3Sopenharmony_ci    }
2464514f5e3Sopenharmony_ci}
2474514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::builtins
248