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 21namespace panda::ecmascript::builtins { 22JSTaggedValue 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 37JSTaggedValue 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 52JSTaggedValue 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 67JSTaggedValue 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 81JSTaggedValue 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 95JSTaggedValue 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 109JSTaggedValue 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 123JSTaggedValue 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 135ITERATE_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 155ITERATE_TYPED_ARRAY(TYPED_ARRAY_CALLBACK) 156#undef TYPED_ARRAY_CALLBACK 157 158JSTaggedValue 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 172JSTaggedValue 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 187JSTaggedValue 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 216ITERATE_INTL(INTL_CALLBACK) 217#undef INTL_CALLBACK 218#endif 219 220void 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